diff mbox series

[4/7] canon: simplify calculation of canonical order

Message ID 20201122152731.10994-5-luc.vanoostenryck@gmail.com (mailing list archive)
State Mainlined, archived
Headers show
Series simplify logical negation | expand

Commit Message

Luc Van Oostenryck Nov. 22, 2020, 3:27 p.m. UTC
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>
---
 linearize.h |  4 ++--
 simplify.c  | 40 +++++++++++++++++++++++++++-------------
 2 files changed, 29 insertions(+), 15 deletions(-)
diff mbox series

Patch

diff --git a/linearize.h b/linearize.h
index 31c754e200c2..2c548d43526f 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 ee485798148b..203472972bca 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)