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