[PATCH 06/22] add a flag to identify commutative & associative ops

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The way how the functions doing the simplification of commutative
or associative binops are called is simple but complicates the
simplification of a specific binop.

Fix this by adding a flag to the opcode table to identify the
commutative and the associative binops and using this flag
to call or not the functions doing the corresponding simplification.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
---
 opcode.def | 50 +++++++++++++++++++--------------------
 opcode.h   |  5 ++++
 simplify.c | 69 ++++++++++++++++++++++++++++++++++++------------------
 3 files changed, 76 insertions(+), 48 deletions(-)

diff --git a/opcode.def b/opcode.def
index 1401d988d73a..c65722f0b9bb 100644
--- a/opcode.def
+++ b/opcode.def
@@ -15,16 +15,16 @@ OPCODE(COMPUTEDGOTO,    BADOP,    BADOP,    BADOP, 1, OPF_NONE)
 OPCODE_RANGE(TERMINATOR, RET, COMPUTEDGOTO)
 
 /* Binary */
-OPCODE(ADD,             BADOP,    BADOP,    FADD,  2, OPF_TARGET)
-OPCODE(SUB,             BADOP,    BADOP,    FSUB,  2, OPF_TARGET)
-OPCODE(MUL,             BADOP,    BADOP,    FMUL,  2, OPF_TARGET)
-OPCODE(DIVU,            BADOP,    BADOP,    FDIV,  2, OPF_TARGET)
-OPCODE(DIVS,            BADOP,    BADOP,    FDIV,  2, OPF_TARGET)
-OPCODE(MODU,            BADOP,    BADOP,    BADOP, 2, OPF_TARGET)
-OPCODE(MODS,            BADOP,    BADOP,    BADOP, 2, OPF_TARGET)
-OPCODE(SHL,             BADOP,    BADOP,    BADOP, 2, OPF_TARGET)
-OPCODE(LSR,             BADOP,    BADOP,    BADOP, 2, OPF_TARGET)
-OPCODE(ASR,             BADOP,    BADOP,    BADOP, 2, OPF_TARGET)
+OPCODE(ADD,             BADOP,    BADOP,    FADD,  2, OPF_TARGET|OPF_COMMU|OPF_ASSOC|OPF_BINOP)
+OPCODE(MUL,             BADOP,    BADOP,    FMUL,  2, OPF_TARGET|OPF_COMMU|OPF_ASSOC|OPF_BINOP)
+OPCODE(SUB,             BADOP,    BADOP,    FSUB,  2, OPF_TARGET|OPF_BINOP)
+OPCODE(DIVU,            BADOP,    BADOP,    FDIV,  2, OPF_TARGET|OPF_BINOP)
+OPCODE(DIVS,            BADOP,    BADOP,    FDIV,  2, OPF_TARGET|OPF_BINOP)
+OPCODE(MODU,            BADOP,    BADOP,    BADOP, 2, OPF_TARGET|OPF_BINOP)
+OPCODE(MODS,            BADOP,    BADOP,    BADOP, 2, OPF_TARGET|OPF_BINOP)
+OPCODE(SHL,             BADOP,    BADOP,    BADOP, 2, OPF_TARGET|OPF_BINOP)
+OPCODE(LSR,             BADOP,    BADOP,    BADOP, 2, OPF_TARGET|OPF_BINOP)
+OPCODE(ASR,             BADOP,    BADOP,    BADOP, 2, OPF_TARGET|OPF_BINOP)
 
 /* Floating-point binops */
 OPCODE(FADD,            BADOP,    BADOP,    BADOP, 2, OPF_TARGET)
@@ -33,9 +33,9 @@ OPCODE(FMUL,            BADOP,    BADOP,    BADOP, 2, OPF_TARGET)
 OPCODE(FDIV,            BADOP,    BADOP,    BADOP, 2, OPF_TARGET)
 
 /* Logical */
-OPCODE(AND,             BADOP,    BADOP,    BADOP, 2, OPF_TARGET)
-OPCODE(OR,              BADOP,    BADOP,    BADOP, 2, OPF_TARGET)
-OPCODE(XOR,             BADOP,    BADOP,    BADOP, 2, OPF_TARGET)
+OPCODE(AND,             BADOP,    BADOP,    BADOP, 2, OPF_TARGET|OPF_COMMU|OPF_ASSOC|OPF_BINOP)
+OPCODE(OR,              BADOP,    BADOP,    BADOP, 2, OPF_TARGET|OPF_COMMU|OPF_ASSOC|OPF_BINOP)
+OPCODE(XOR,             BADOP,    BADOP,    BADOP, 2, OPF_TARGET|OPF_COMMU|OPF_ASSOC|OPF_BINOP)
 OPCODE_RANGE(BINARY, ADD, XOR)
 
 /* floating-point comparison */
@@ -56,21 +56,21 @@ OPCODE(FCMP_UNO,        FCMP_ORD, FCMP_UNO, BADOP, 2, OPF_TARGET)
 OPCODE_RANGE(FPCMP, FCMP_ORD, FCMP_UNO)
 
 /* Binary comparison */
-OPCODE(SET_EQ,          SET_NE,   SET_EQ,   FCMP_OEQ, 2, OPF_TARGET)
-OPCODE(SET_LT,          SET_GE,   SET_GT,   FCMP_OLT, 2, OPF_TARGET)
-OPCODE(SET_LE,          SET_GT,   SET_GE,   FCMP_OLE, 2, OPF_TARGET)
-OPCODE(SET_GE,          SET_LT,   SET_LE,   FCMP_OGE, 2, OPF_TARGET)
-OPCODE(SET_GT,          SET_LE,   SET_LT,   FCMP_OGT, 2, OPF_TARGET)
-OPCODE(SET_B,           SET_AE,   SET_A,    FCMP_OLT, 2, OPF_TARGET)
-OPCODE(SET_BE,          SET_A,    SET_AE,   FCMP_OLE, 2, OPF_TARGET)
-OPCODE(SET_AE,          SET_B,    SET_BE,   FCMP_OGE, 2, OPF_TARGET)
-OPCODE(SET_A,           SET_BE,   SET_B,    FCMP_OGT, 2, OPF_TARGET)
-OPCODE(SET_NE,          SET_EQ,   SET_NE,   FCMP_UNE, 2, OPF_TARGET)
+OPCODE(SET_EQ,          SET_NE,   SET_EQ,   FCMP_OEQ, 2, OPF_TARGET|OPF_BINOP|OPF_COMPARE|OPF_COMMU)
+OPCODE(SET_LT,          SET_GE,   SET_GT,   FCMP_OLT, 2, OPF_TARGET|OPF_BINOP|OPF_COMPARE)
+OPCODE(SET_LE,          SET_GT,   SET_GE,   FCMP_OLE, 2, OPF_TARGET|OPF_BINOP|OPF_COMPARE)
+OPCODE(SET_GE,          SET_LT,   SET_LE,   FCMP_OGE, 2, OPF_TARGET|OPF_BINOP|OPF_COMPARE)
+OPCODE(SET_GT,          SET_LE,   SET_LT,   FCMP_OGT, 2, OPF_TARGET|OPF_BINOP|OPF_COMPARE)
+OPCODE(SET_B,           SET_AE,   SET_A,    FCMP_OLT, 2, OPF_TARGET|OPF_BINOP|OPF_COMPARE)
+OPCODE(SET_BE,          SET_A,    SET_AE,   FCMP_OLE, 2, OPF_TARGET|OPF_BINOP|OPF_COMPARE)
+OPCODE(SET_AE,          SET_B,    SET_BE,   FCMP_OGE, 2, OPF_TARGET|OPF_BINOP|OPF_COMPARE)
+OPCODE(SET_A,           SET_BE,   SET_B,    FCMP_OGT, 2, OPF_TARGET|OPF_BINOP|OPF_COMPARE)
+OPCODE(SET_NE,          SET_EQ,   SET_NE,   FCMP_UNE, 2, OPF_TARGET|OPF_BINOP|OPF_COMPARE|OPF_COMMU)
 OPCODE_RANGE(BINCMP, SET_EQ, SET_NE)
 
 /* Uni */
-OPCODE(NOT,             BADOP,    BADOP,    BADOP, 1, OPF_TARGET)
-OPCODE(NEG,             BADOP,    BADOP,    FNEG,  1, OPF_TARGET)
+OPCODE(NOT,             BADOP,    BADOP,    BADOP, 1, OPF_TARGET|OPF_UNOP)
+OPCODE(NEG,             BADOP,    BADOP,    FNEG,  1, OPF_TARGET|OPF_UNOP)
 OPCODE(FNEG,            BADOP,    BADOP,    BADOP, 1, OPF_TARGET)
 OPCODE(TRUNC,           BADOP,    BADOP,    BADOP, 1, OPF_TARGET)
 OPCODE(ZEXT,            BADOP,    BADOP,    BADOP, 1, OPF_TARGET)
diff --git a/opcode.h b/opcode.h
index e426bed4f7e2..bb94ec81c832 100644
--- a/opcode.h
+++ b/opcode.h
@@ -20,6 +20,11 @@ extern const struct opcode_table {
 	unsigned int flags:6;
 #define			OPF_NONE	0
 #define			OPF_TARGET	(1 << 0)
+#define			OPF_COMMU	(1 << 1)
+#define			OPF_ASSOC	(1 << 2)
+#define			OPF_UNOP	(1 << 3)
+#define			OPF_BINOP	(1 << 4)
+#define			OPF_COMPARE	(1 << 5)
 } opcode_table[];
 
 
diff --git a/simplify.c b/simplify.c
index 3cac124f7d9f..db7a1e47ff0a 100644
--- a/simplify.c
+++ b/simplify.c
@@ -1736,35 +1736,57 @@ found:
 
 int simplify_instruction(struct instruction *insn)
 {
+	unsigned flags;
+	int changed = 0;
+
 	if (!insn->bb)
 		return 0;
-	switch (insn->opcode) {
-	case OP_ADD: case OP_MUL:
-	case OP_AND: case OP_OR: case OP_XOR:
-		canonicalize_commutative(insn);
-		if (simplify_binop(insn))
-			return REPEAT_CSE;
-		return simplify_associative_binop(insn);
 
-	case OP_SET_EQ: case OP_SET_NE:
-		canonicalize_commutative(insn);
-		return simplify_binop(insn);
+	flags = opcode_table[insn->opcode].flags;
+	if (flags & OPF_COMMU)
+		canonicalize_commutative(insn) ;
+	if (flags & OPF_COMPARE)
+		canonicalize_compare(insn) ;
+	if (flags & OPF_BINOP) {
+		if ((changed = simplify_binop(insn)))
+			return changed;
+	}
+	if (flags & OPF_ASSOC) {
+		if ((changed = simplify_associative_binop(insn)))
+			return changed;
+	}
+	if (flags & OPF_UNOP) {
+		if ((changed = simplify_unop(insn)))
+			return changed;
+	}
 
-	case OP_SET_LE: case OP_SET_GE:
-	case OP_SET_LT: case OP_SET_GT:
-	case OP_SET_B:  case OP_SET_A:
-	case OP_SET_BE: case OP_SET_AE:
-		canonicalize_compare(insn);
-		/* fall through */
+	switch (insn->opcode) {
+	case OP_ADD:
 	case OP_SUB:
-	case OP_DIVU: case OP_DIVS:
-	case OP_MODU: case OP_MODS:
+	case OP_MUL:
+	case OP_AND:
+	case OP_OR:
+	case OP_XOR:
 	case OP_SHL:
-	case OP_LSR: case OP_ASR:
-		return simplify_binop(insn);
-
-	case OP_NOT: case OP_NEG: case OP_FNEG:
-		return simplify_unop(insn);
+	case OP_LSR:
+	case OP_ASR:
+	case OP_NOT:
+	case OP_NEG:
+	case OP_DIVU:
+	case OP_DIVS:
+	case OP_MODU:
+	case OP_MODS:
+	case OP_SET_EQ:
+	case OP_SET_NE:
+	case OP_SET_LE:
+	case OP_SET_GE:
+	case OP_SET_LT:
+	case OP_SET_GT:
+	case OP_SET_B:
+	case OP_SET_A:
+	case OP_SET_BE:
+	case OP_SET_AE:
+		break;
 	case OP_LOAD:
 		if (!has_users(insn->target))
 			return kill_instruction(insn);
@@ -1778,6 +1800,7 @@ int simplify_instruction(struct instruction *insn)
 	case OP_SEXT: case OP_ZEXT:
 	case OP_TRUNC:
 		return simplify_cast(insn);
+	case OP_FNEG:
 	case OP_FCVTU: case OP_FCVTS:
 	case OP_UCVTF: case OP_SCVTF:
 	case OP_FCVTF:
-- 
2.28.0




[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux