diff options
| author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2018-08-31 00:05:51 +0200 |
|---|---|---|
| committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2018-08-31 00:05:51 +0200 |
| commit | ce2a7be626471bb155462aea3a6da24f374f9d04 (patch) | |
| tree | 08cd1bb808adde2605f1ad982599a0b3186e3195 | |
| parent | b814c73f9cef04c1162084cc64e4cbbe9e2da97b (diff) | |
| parent | 2be8fdea5dc4160898bc820e05f65c6f1cd149cb (diff) | |
| download | sparse-dev-ce2a7be626471bb155462aea3a6da24f374f9d04.tar.gz | |
Merge branch 'opcode' into tip
* consolidate instruction's properties into an opcode table
| -rw-r--r-- | Documentation/IR.rst | 12 | ||||
| -rw-r--r-- | cse.c | 11 | ||||
| -rw-r--r-- | flow.h | 1 | ||||
| -rw-r--r-- | linearize.c | 8 | ||||
| -rw-r--r-- | linearize.h | 119 | ||||
| -rw-r--r-- | liveness.c | 5 | ||||
| -rw-r--r-- | opcode.c | 49 | ||||
| -rw-r--r-- | opcode.def | 114 | ||||
| -rw-r--r-- | opcode.h | 13 | ||||
| -rw-r--r-- | simplify.c | 28 |
10 files changed, 177 insertions, 183 deletions
diff --git a/Documentation/IR.rst b/Documentation/IR.rst index 0419ac41..8ffc921a 100644 --- a/Documentation/IR.rst +++ b/Documentation/IR.rst @@ -241,6 +241,12 @@ Unary ops * .target: result of the operation (must be a floating-point type) * .type: type of .target +.. op:: OP_SYMADDR + Create a pseudo corresponding to the address of a symbol. + + * .src: input symbol (must be a PSEUDO_SYM) + * .target: symbol's address + .. op:: OP_COPY Copy (only needed after out-of-SSA). @@ -327,12 +333,6 @@ Memory ops Others ------ -.. op:: OP_SYMADDR - Create a pseudo corresponding to the address of a symbol. - - * .symbol: (pseudo_t) input symbol (alias .src) - * .target: symbol's address - .. op:: OP_SETFVAL Create a pseudo corresponding to a floating-point literal. @@ -76,6 +76,7 @@ void cse_collect(struct instruction *insn) /* Unary */ case OP_NOT: case OP_NEG: case OP_FNEG: + case OP_SYMADDR: hash += hashval(insn->src1); break; @@ -87,10 +88,6 @@ void cse_collect(struct instruction *insn) hash += hashval(insn->fvalue); break; - case OP_SYMADDR: - hash += hashval(insn->symbol); - break; - case OP_SEXT: case OP_ZEXT: case OP_TRUNC: case OP_PTRCAST: @@ -213,15 +210,11 @@ static int insn_compare(const void *_i1, const void *_i2) /* Unary */ case OP_NOT: case OP_NEG: case OP_FNEG: + case OP_SYMADDR: if (i1->src1 != i2->src1) return i1->src1 < i2->src1 ? -1 : 1; break; - case OP_SYMADDR: - if (i1->symbol != i2->symbol) - return i1->symbol < i2->symbol ? -1 : 1; - break; - case OP_SETVAL: if (i1->val != i2->val) return i1->val < i2->val ? -1 : 1; @@ -20,6 +20,7 @@ extern void simplify_memops(struct entrypoint *ep); extern void pack_basic_blocks(struct entrypoint *ep); extern void convert_instruction_target(struct instruction *insn, pseudo_t src); +extern void remove_dead_insns(struct entrypoint *); extern int simplify_instruction(struct instruction *); extern void kill_bb(struct basic_block *); diff --git a/linearize.c b/linearize.c index c4f38456..3ef44227 100644 --- a/linearize.c +++ b/linearize.c @@ -351,11 +351,6 @@ const char *show_instruction(struct instruction *insn) buf += sprintf(buf, "%s", show_label(insn->bb_true)); break; - case OP_SYMADDR: - buf += sprintf(buf, "%s <- ", show_pseudo(insn->target)); - buf += sprintf(buf, "%s", show_pseudo(insn->symbol)); - break; - case OP_SETVAL: { struct expression *expr = insn->val; buf += sprintf(buf, "%s <- ", show_pseudo(insn->target)); @@ -481,6 +476,7 @@ const char *show_instruction(struct instruction *insn) case OP_NOT: case OP_NEG: case OP_FNEG: + case OP_SYMADDR: buf += sprintf(buf, "%s <- %s", show_pseudo(insn->target), show_pseudo(insn->src1)); break; @@ -1106,7 +1102,7 @@ static pseudo_t add_symbol_address(struct entrypoint *ep, struct symbol *sym) pseudo_t target = alloc_pseudo(insn); insn->target = target; - use_pseudo(insn, symbol_pseudo(ep, sym), &insn->symbol); + use_pseudo(insn, symbol_pseudo(ep, sym), &insn->src); add_one_insn(ep, insn); return target; } diff --git a/linearize.h b/linearize.h index 17f746a8..69537ee1 100644 --- a/linearize.h +++ b/linearize.h @@ -126,9 +126,6 @@ struct instruction { pseudo_t base; unsigned from, len; }; - struct /* symaddr */ { - pseudo_t symbol; /* Subtle: same offset as "src" !! */ - }; struct /* setval */ { struct expression *val; }; @@ -152,122 +149,6 @@ struct instruction { }; }; -enum opcode { - OP_BADOP, - - /* Entry */ - OP_ENTRY, - - /* Terminator */ - OP_TERMINATOR, - OP_RET = OP_TERMINATOR, - OP_BR, - OP_CBR, - OP_SWITCH, - OP_COMPUTEDGOTO, - OP_TERMINATOR_END = OP_COMPUTEDGOTO, - - /* Binary */ - OP_BINARY, - OP_ADD = OP_BINARY, - OP_SUB, - OP_MUL, - OP_DIVU, OP_DIVS, - OP_MODU, OP_MODS, - OP_SHL, - OP_LSR, OP_ASR, - - /* Floating-point binops */ - OP_FADD, - OP_FSUB, - OP_FMUL, - OP_FDIV, - - /* Logical */ - OP_AND, - OP_OR, - OP_XOR, - OP_BINARY_END = OP_XOR, - - /* floating-point comparison */ - OP_FPCMP, - OP_FCMP_ORD = OP_FPCMP, - OP_FCMP_OEQ, - OP_FCMP_ONE, - OP_FCMP_OLE, - OP_FCMP_OGE, - OP_FCMP_OLT, - OP_FCMP_OGT, - OP_FCMP_UEQ, - OP_FCMP_UNE, - OP_FCMP_ULE, - OP_FCMP_UGE, - OP_FCMP_ULT, - OP_FCMP_UGT, - OP_FCMP_UNO, - OP_FPCMP_END = OP_FCMP_UNO, - - /* Binary comparison */ - OP_BINCMP, - OP_SET_EQ = OP_BINCMP, - OP_SET_NE, - OP_SET_LE, - OP_SET_GE, - OP_SET_LT, - OP_SET_GT, - OP_SET_B, - OP_SET_A, - OP_SET_BE, - OP_SET_AE, - OP_BINCMP_END = OP_SET_AE, - - /* Uni */ - OP_UNOP, - OP_NOT = OP_UNOP, - OP_NEG, - OP_FNEG, - - /* Casts */ - OP_TRUNC, - OP_ZEXT, OP_SEXT, - OP_FCVTU, OP_FCVTS, - OP_UCVTF, OP_SCVTF, - OP_FCVTF, - OP_UTPTR, - OP_PTRTU, - OP_PTRCAST, - OP_UNOP_END = OP_PTRCAST, - - /* Select - three input values */ - OP_SEL, - - /* Memory */ - OP_LOAD, - OP_STORE, - OP_SETVAL, - OP_SETFVAL, - OP_SYMADDR, - - /* Other */ - OP_PHI, - OP_PHISOURCE, - OP_INLINED_CALL, - OP_CALL, - OP_SLICE, - OP_NOP, - OP_DEATHNOTE, - OP_ASM, - - /* Sparse tagging (line numbers, context, whatever) */ - OP_CONTEXT, - OP_RANGE, - - /* Needed to translate SSA back to normal form */ - OP_COPY, - - OP_LAST, /* keep this one last! */ -}; - struct basic_block_list; struct instruction_list; @@ -72,6 +72,7 @@ static void track_instruction_usage(struct basic_block *bb, struct instruction * /* Uni */ case OP_UNOP ... OP_UNOP_END: + case OP_SYMADDR: USES(src1); DEFINES(target); break; @@ -93,10 +94,6 @@ static void track_instruction_usage(struct basic_block *bb, struct instruction * DEFINES(target); break; - case OP_SYMADDR: - USES(symbol); DEFINES(target); - break; - /* Other */ case OP_PHI: /* Phi-nodes are "backwards" nodes. Their def doesn't matter */ @@ -20,42 +20,19 @@ * THE SOFTWARE. */ -#include "linearize.h" +#include "opcode.h" const struct opcode_table opcode_table[OP_LAST] = { - [OP_SET_EQ] = { .negate = OP_SET_NE, .swap = OP_SET_EQ, .to_float = OP_FCMP_OEQ, }, - [OP_SET_NE] = { .negate = OP_SET_EQ, .swap = OP_SET_NE, .to_float = OP_FCMP_UNE, }, - [OP_SET_LT] = { .negate = OP_SET_GE, .swap = OP_SET_GT, .to_float = OP_FCMP_OLT, }, - [OP_SET_LE] = { .negate = OP_SET_GT, .swap = OP_SET_GE, .to_float = OP_FCMP_OLE, }, - [OP_SET_GE] = { .negate = OP_SET_LT, .swap = OP_SET_LE, .to_float = OP_FCMP_OGE, }, - [OP_SET_GT] = { .negate = OP_SET_LE, .swap = OP_SET_LT, .to_float = OP_FCMP_OGT, }, - [OP_SET_B ] = { .negate = OP_SET_AE, .swap = OP_SET_A , .to_float = OP_FCMP_OLT, }, - [OP_SET_BE] = { .negate = OP_SET_A , .swap = OP_SET_AE, .to_float = OP_FCMP_OLE, }, - [OP_SET_AE] = { .negate = OP_SET_B , .swap = OP_SET_BE, .to_float = OP_FCMP_OGE, }, - [OP_SET_A ] = { .negate = OP_SET_BE, .swap = OP_SET_B , .to_float = OP_FCMP_OGT, }, - - [OP_FCMP_ORD] = { .negate = OP_FCMP_UNO, .swap = OP_FCMP_ORD, }, - [OP_FCMP_UNO] = { .negate = OP_FCMP_ORD, .swap = OP_FCMP_UNO, }, - - [OP_FCMP_OEQ] = { .negate = OP_FCMP_UNE, .swap = OP_FCMP_OEQ, }, - [OP_FCMP_ONE] = { .negate = OP_FCMP_UEQ, .swap = OP_FCMP_ONE, }, - [OP_FCMP_UEQ] = { .negate = OP_FCMP_ONE, .swap = OP_FCMP_UEQ, }, - [OP_FCMP_UNE] = { .negate = OP_FCMP_OEQ, .swap = OP_FCMP_UNE, }, - - [OP_FCMP_OLT] = { .negate = OP_FCMP_UGE, .swap = OP_FCMP_OGT, }, - [OP_FCMP_OLE] = { .negate = OP_FCMP_UGT, .swap = OP_FCMP_OGE, }, - [OP_FCMP_OGE] = { .negate = OP_FCMP_ULT, .swap = OP_FCMP_OLE, }, - [OP_FCMP_OGT] = { .negate = OP_FCMP_ULE, .swap = OP_FCMP_OLT, }, - - [OP_FCMP_ULT] = { .negate = OP_FCMP_OGE, .swap = OP_FCMP_UGT, }, - [OP_FCMP_ULE] = { .negate = OP_FCMP_OGT, .swap = OP_FCMP_UGE, }, - [OP_FCMP_UGE] = { .negate = OP_FCMP_OLT, .swap = OP_FCMP_ULE, }, - [OP_FCMP_UGT] = { .negate = OP_FCMP_OLE, .swap = OP_FCMP_ULT, }, - - [OP_ADD] = { .to_float = OP_FADD, }, - [OP_SUB] = { .to_float = OP_FSUB, }, - [OP_MUL] = { .to_float = OP_FMUL, }, - [OP_DIVS] = { .to_float = OP_FDIV, }, - [OP_DIVU] = { .to_float = OP_FDIV, }, - [OP_NEG] = { .to_float = OP_FNEG, }, +#define OPCODE(OP,NG,SW,TF,N,FL) \ + [OP_##OP] = { \ + .negate = OP_##NG, \ + .swap = OP_##SW, \ + .to_float = OP_##TF, \ + .arity = N, \ + .flags = FL, \ + }, +#define OPCODE_RANGE(OP,S,E) +#include "opcode.def" +#undef OPCODE +#undef OPCODE_RANGE }; diff --git a/opcode.def b/opcode.def new file mode 100644 index 00000000..57d827f4 --- /dev/null +++ b/opcode.def @@ -0,0 +1,114 @@ +// OPCODE negated swaped float arity, flags + +OPCODE(BADOP, BADOP, BADOP, BADOP, 0, OPF_NONE) + +/* Entry */ +OPCODE(ENTRY, BADOP, BADOP, BADOP, 0, OPF_NONE) + +/* Terminator */ +OPCODE(RET, BADOP, BADOP, BADOP, 1, OPF_NONE) +OPCODE(BR, BADOP, BADOP, BADOP, 0, OPF_NONE) +OPCODE(CBR, BADOP, BADOP, BADOP, 1, OPF_NONE) +OPCODE(SWITCH, BADOP, BADOP, BADOP, 1, OPF_NONE) +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) + +/* Floating-point binops */ +OPCODE(FADD, BADOP, BADOP, BADOP, 2, OPF_TARGET) +OPCODE(FSUB, BADOP, BADOP, BADOP, 2, OPF_TARGET) +OPCODE(FMUL, BADOP, BADOP, BADOP, 2, OPF_TARGET) +OPCODE(FDIV, BADOP, BADOP, BADOP, 2, OPF_TARGET) + +/* Logical */ +OPCODE(AND_BOOL, BADOP, BADOP, BADOP, 2, OPF_TARGET) +OPCODE(OR_BOOL, BADOP, BADOP, BADOP, 2, OPF_TARGET) +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_RANGE(BINARY, ADD, XOR) + +/* floating-point comparison */ +OPCODE(FCMP_ORD, FCMP_UNO, FCMP_ORD, BADOP, 2, OPF_TARGET) +OPCODE(FCMP_OEQ, FCMP_UNE, FCMP_OEQ, BADOP, 2, OPF_TARGET) +OPCODE(FCMP_ONE, FCMP_UEQ, FCMP_ONE, BADOP, 2, OPF_TARGET) +OPCODE(FCMP_UEQ, FCMP_ONE, FCMP_UEQ, BADOP, 2, OPF_TARGET) +OPCODE(FCMP_UNE, FCMP_OEQ, FCMP_UNE, BADOP, 2, OPF_TARGET) +OPCODE(FCMP_OLT, FCMP_UGE, FCMP_OGT, BADOP, 2, OPF_TARGET) +OPCODE(FCMP_OLE, FCMP_UGT, FCMP_OGE, BADOP, 2, OPF_TARGET) +OPCODE(FCMP_OGE, FCMP_ULT, FCMP_OLE, BADOP, 2, OPF_TARGET) +OPCODE(FCMP_OGT, FCMP_ULE, FCMP_OLT, BADOP, 2, OPF_TARGET) +OPCODE(FCMP_ULT, FCMP_OGE, FCMP_UGT, BADOP, 2, OPF_TARGET) +OPCODE(FCMP_ULE, FCMP_OGT, FCMP_UGE, BADOP, 2, OPF_TARGET) +OPCODE(FCMP_UGE, FCMP_OLT, FCMP_ULE, BADOP, 2, OPF_TARGET) +OPCODE(FCMP_UGT, FCMP_OLE, FCMP_ULT, BADOP, 2, OPF_TARGET) +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_RANGE(BINCMP, SET_EQ, SET_NE) + +/* Uni */ +OPCODE(NOT, BADOP, BADOP, BADOP, 1, OPF_TARGET) +OPCODE(NEG, BADOP, BADOP, FNEG, 1, OPF_TARGET) +OPCODE(FNEG, BADOP, BADOP, BADOP, 1, OPF_TARGET) +OPCODE(TRUNC, BADOP, BADOP, BADOP, 1, OPF_TARGET) +OPCODE(ZEXT, BADOP, BADOP, BADOP, 1, OPF_TARGET) +OPCODE(SEXT, BADOP, BADOP, BADOP, 1, OPF_TARGET) +OPCODE(FCVTU, BADOP, BADOP, BADOP, 1, OPF_TARGET) +OPCODE(FCVTS, BADOP, BADOP, BADOP, 1, OPF_TARGET) +OPCODE(UCVTF, BADOP, BADOP, BADOP, 1, OPF_TARGET) +OPCODE(SCVTF, BADOP, BADOP, BADOP, 1, OPF_TARGET) +OPCODE(FCVTF, BADOP, BADOP, BADOP, 1, OPF_TARGET) +OPCODE(UTPTR, BADOP, BADOP, BADOP, 1, OPF_TARGET) +OPCODE(PTRTU, BADOP, BADOP, BADOP, 1, OPF_TARGET) +OPCODE(PTRCAST, BADOP, BADOP, BADOP, 1, OPF_TARGET) +OPCODE_RANGE(UNOP, NOT, PTRCAST) +OPCODE(SYMADDR, BADOP, BADOP, BADOP, 1, OPF_TARGET) +OPCODE(SLICE, BADOP, BADOP, BADOP, 1, OPF_TARGET) + +/* Select - three input values */ +OPCODE(SEL, BADOP, BADOP, BADOP, 3, OPF_TARGET) + +/* Memory */ +OPCODE(LOAD, BADOP, BADOP, BADOP, 1, OPF_TARGET) +OPCODE(STORE, BADOP, BADOP, BADOP, 1, OPF_NONE) + +/* Other */ +OPCODE(PHISOURCE, BADOP, BADOP, BADOP, 1, OPF_TARGET) +OPCODE(PHI, BADOP, BADOP, BADOP, 0, OPF_TARGET) +OPCODE(SETVAL, BADOP, BADOP, BADOP, 0, OPF_TARGET) +OPCODE(SETFVAL, BADOP, BADOP, BADOP, 0, OPF_TARGET) +OPCODE(CALL, BADOP, BADOP, BADOP, 1, OPF_TARGET) +OPCODE(INLINED_CALL, BADOP, BADOP, BADOP, 0, OPF_NONE) +OPCODE(NOP, BADOP, BADOP, BADOP, 0, OPF_NONE) +OPCODE(DEATHNOTE, BADOP, BADOP, BADOP, 0, OPF_NONE) +OPCODE(ASM, BADOP, BADOP, BADOP, 0, OPF_NONE) + +/* Sparse tagging (line numbers, context, whatever) */ +OPCODE(CONTEXT, BADOP, BADOP, BADOP, 0, OPF_NONE) +OPCODE(RANGE, BADOP, BADOP, BADOP, 3, OPF_NONE) + +/* Needed to translate SSA back to normal form */ +OPCODE(COPY, BADOP, BADOP, BADOP, 1, OPF_TARGET) @@ -3,10 +3,23 @@ #include "symbol.h" +enum opcode { +#define OPCODE(OP,NG,SW,TF,N,FL) OP_##OP, +#define OPCODE_RANGE(OP,S,E) OP_##OP = OP_##S, OP_##OP##_END = OP_##E, +#include "opcode.def" +#undef OPCODE +#undef OPCODE_RANGE + OP_LAST, /* keep this one last! */ +}; + extern const struct opcode_table { int negate:8; int swap:8; int to_float:8; + unsigned int arity:2; + unsigned int flags:6; +#define OPF_NONE 0 +#define OPF_TARGET (1 << 0) } opcode_table[]; @@ -305,7 +305,7 @@ int kill_insn(struct instruction *insn, int force) break; case OP_SYMADDR: - kill_use(&insn->symbol); + kill_use(&insn->src); repeat_phase |= REPEAT_SYMBOL_CLEANUP; break; @@ -369,6 +369,28 @@ static int dead_insn(struct instruction *insn, pseudo_t *src1, pseudo_t *src2, p return REPEAT_CSE; } +static inline bool has_target(struct instruction *insn) +{ + return opcode_table[insn->opcode].flags & OPF_TARGET; +} + +void remove_dead_insns(struct entrypoint *ep) +{ + struct basic_block *bb; + + FOR_EACH_PTR_REVERSE(ep->bbs, bb) { + struct instruction *insn; + FOR_EACH_PTR_REVERSE(bb->insns, insn) { + if (!insn->bb) + continue; + if (!has_target(insn)) + continue; + if (!has_users(insn->target)) + kill_instruction(insn); + } END_FOR_EACH_PTR_REVERSE(insn); + } END_FOR_EACH_PTR_REVERSE(bb); +} + static inline int constant(pseudo_t pseudo) { return pseudo->type == PSEUDO_VAL; @@ -1704,9 +1726,9 @@ int simplify_instruction(struct instruction *insn) case OP_STORE: return simplify_memop(insn); case OP_SYMADDR: - if (dead_insn(insn, &insn->symbol, NULL, NULL)) + if (dead_insn(insn, &insn->src, NULL, NULL)) return REPEAT_CSE | REPEAT_SYMBOL_CLEANUP; - return replace_with_pseudo(insn, insn->symbol); + return replace_with_pseudo(insn, insn->src); case OP_SEXT: case OP_ZEXT: case OP_TRUNC: return simplify_cast(insn); |
