diff options
| -rw-r--r-- | linearize.h | 4 | ||||
| -rw-r--r-- | simplify.c | 40 |
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 { @@ -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) |
