aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-11-22 13:41:12 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-11-22 15:58:05 +0100
commit84f84262a122875e930585dee346124b316d376f (patch)
tree0b290cd4e8a49b8d34c8ec5357f3e57b7e8d5078
parentef00ea2fa5203a2e3da3e3c7f2c46668d66c31c9 (diff)
downloadsparse-84f84262a122875e930585dee346124b316d376f.tar.gz
canon: simplify calculation of canonical order
The calculation of the canonical order is currently somehow complicated. Fix this by reordering the definition of the different type of pseudos so that they are already in canonical order and just comparing the types to determine the order. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--linearize.h4
-rw-r--r--simplify.c40
2 files changed, 29 insertions, 15 deletions
diff --git a/linearize.h b/linearize.h
index 31c754e2..2c548d43 100644
--- a/linearize.h
+++ b/linearize.h
@@ -24,11 +24,11 @@ DECLARE_PTRMAP(phi_map, struct symbol *, pseudo_t);
enum pseudo_type {
PSEUDO_VOID,
PSEUDO_UNDEF,
+ PSEUDO_PHI,
PSEUDO_REG,
+ PSEUDO_ARG,
PSEUDO_SYM,
PSEUDO_VAL,
- PSEUDO_ARG,
- PSEUDO_PHI,
};
struct pseudo {
diff --git a/simplify.c b/simplify.c
index ee485798..20347297 100644
--- a/simplify.c
+++ b/simplify.c
@@ -1462,22 +1462,36 @@ static int switch_pseudo(struct instruction *insn1, pseudo_t *pp1, struct instru
return REPEAT_CSE;
}
+///
+// check if the given pseudos are in canonical order
+//
+// The canonical order is VOID < UNDEF < PHI < REG < ARG < SYM < VAL
+// The rationale is:
+// * VALs at right (they don't need a definition)
+// * REGs at left (they need a defining instruction)
+// * SYMs & ARGs between REGs & VALs
+// * REGs & ARGs are ordered between themselves by their internal number
+// * SYMs are ordered between themselves by address
+// * VOID, UNDEF and PHI are uninteresting (but VOID should have type 0)
static int canonical_order(pseudo_t p1, pseudo_t p2)
{
- /* symbol/constants on the right */
- if (p1->type == PSEUDO_VAL)
- return p2->type == PSEUDO_VAL;
-
- if (p1->type == PSEUDO_SYM)
- return p2->type == PSEUDO_SYM || p2->type == PSEUDO_VAL;
-
- if (p1->type == PSEUDO_ARG)
- return (p2->type == PSEUDO_ARG && p1->nr <= p2->nr) || p2->type == PSEUDO_VAL || p2->type == PSEUDO_SYM;
+ int t1 = p1->type;
+ int t2 = p2->type;
- if (p1->type == PSEUDO_REG)
- return (p2->type == PSEUDO_REG && p1->nr <= p2->nr) || p2->type == PSEUDO_VAL || p2->type == PSEUDO_SYM || p2->type == PSEUDO_ARG;
-
- return 1;
+ /* symbol/constants on the right */
+ if (t1 < t2)
+ return 1;
+ if (t1 > t2)
+ return 0;
+ switch (t1) {
+ case PSEUDO_SYM:
+ return p1->sym <= p2->sym;
+ case PSEUDO_REG:
+ case PSEUDO_ARG:
+ return p1->nr <= p2->nr;
+ default:
+ return 1;
+ }
}
static int canonicalize_commutative(struct instruction *insn)