aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-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)