diff options
author | João Valverde <j@v6e.pt> | 2022-03-19 00:14:07 +0000 |
---|---|---|
committer | João Valverde <j@v6e.pt> | 2022-03-21 17:36:41 +0000 |
commit | 54d8627c9a0801e5e65717709db1be8c2cfcd645 (patch) | |
tree | f372f3dc1d5a77647b37a9618059bc1a34710aee | |
parent | d60f2580bafaa4596e5d0ead95646910aa46266c (diff) |
dfilter: Add more comments to optimization pass
-rw-r--r-- | epan/dfilter/gencode.c | 54 |
1 files changed, 30 insertions, 24 deletions
diff --git a/epan/dfilter/gencode.c b/epan/dfilter/gencode.c index 8e02e1d0b9..e2f0fef807 100644 --- a/epan/dfilter/gencode.c +++ b/epan/dfilter/gencode.c @@ -452,56 +452,62 @@ gencode(dfwork_t *dfw, stnode_t *st_node) } -void -dfw_gencode(dfwork_t *dfw) +static void +optimize(dfwork_t *dfw) { int id, id1, length; dfvm_insn_t *insn, *insn1, *prev; dfvm_value_t *arg1; - dfw->insns = g_ptr_array_new(); - dfw->loaded_fields = g_hash_table_new(g_direct_hash, g_direct_equal); - dfw->interesting_fields = g_hash_table_new(g_direct_hash, g_direct_equal); - gencode(dfw, dfw->st_root); - dfw_append_insn(dfw, dfvm_insn_new(RETURN)); - - /* fixup goto */ length = dfw->insns->len; for (id = 0, prev = NULL; id < length; prev = insn, id++) { insn = (dfvm_insn_t *)g_ptr_array_index(dfw->insns, id); arg1 = insn->arg1; if (insn->op == IF_TRUE_GOTO || insn->op == IF_FALSE_GOTO) { - dfvm_opcode_t revert = (insn->op == IF_FALSE_GOTO)?IF_TRUE_GOTO:IF_FALSE_GOTO; + /* Try to optimize branch jumps */ + dfvm_opcode_t revert = (insn->op == IF_FALSE_GOTO) ? IF_TRUE_GOTO : IF_FALSE_GOTO; id1 = arg1->value.numeric; - do { + for (;;) { insn1 = (dfvm_insn_t*)g_ptr_array_index(dfw->insns, id1); if (insn1->op == revert) { - /* this one is always false and the branch is not taken*/ + /* Skip this one; it is always false and the branch is not taken */ id1 = id1 +1; continue; } - else if (insn1->op == READ_TREE && prev && prev->op == READ_TREE && + if (insn1->op == READ_TREE && prev && prev->op == READ_TREE && prev->arg2->value.numeric == insn1->arg2->value.numeric) { - /* hack if it's the same register it's the same field - * and it returns the same value - */ + /* Skip this one; hack if it's the same register it's the same field + * and it returns the same value */ id1 = id1 +1; continue; } - else if (insn1->op != insn->op) { - /* bail out */ - arg1 = insn->arg1; - arg1->value.numeric = id1; - break; + if (insn1->op == insn->op) { + /* The branch jumps to the same branch instruction so + * coalesce the jumps */ + arg1 = insn1->arg1; + id1 = arg1->value.numeric; + continue; } - arg1 = insn1->arg1; - id1 = arg1->value.numeric; - } while (1); + /* Finished */ + arg1 = insn->arg1; + arg1->value.numeric = id1; + break; + } } } } +void +dfw_gencode(dfwork_t *dfw) +{ + dfw->insns = g_ptr_array_new(); + dfw->loaded_fields = g_hash_table_new(g_direct_hash, g_direct_equal); + dfw->interesting_fields = g_hash_table_new(g_direct_hash, g_direct_equal); + gencode(dfw, dfw->st_root); + dfw_append_insn(dfw, dfvm_insn_new(RETURN)); + optimize(dfw); +} typedef struct { |