- * encode a DAG staring by the IR-node node
- *
- * @param node The root node of the graph
- * @param buf The code buffer to store the bitstring in
- * @param max_depth The maximum depth for descending
- *
- * @return The depth of the encoded graph (without cycles)
- */
-static int encode_node(ir_node *node, CODE_BUFFER *buf, int max_depth)
-{
- codec_env_t env;
- int res;
-
- env.buf = buf;
- env.curr_id = 1; /* 0 is used for special purpose */
- env.options = status->options;
- env.dmp = NULL;
-
- if (env.options & OPT_ENC_DAG)
- env.id_set = new_set(addr_cmp, 32);
- else
- env.id_set = NULL;
-
- /* encode options if any */
- if (env.options) {
- put_tag(buf, VLC_TAG_OPTION);
- put_code(buf, env.options);
- }
-
- res = _encode_node(node, max_depth, &env);
-
- if (env.options & OPT_ENC_DAG)
- del_set(env.id_set);
-
- return max_depth - res;
-}
-
-/**
- * decode an IR-node, recursive walker
- */
-static void _decode_node(unsigned parent, int position, codec_env_t *env)
-{
- unsigned code;
- unsigned op_code;
- unsigned mode_code = 0;
- long iconst;
- void *attr = NULL;
-
- code = next_tag(env->buf);
- if (code == VLC_TAG_REF) { /* it's a REF */
- code = get_code(env->buf);
-
- /* dump the edge */
- if (parent) {
- int edge_mode = 0;
- /*
- * the mode of a Firm edge can be either computed from its target or
- * from its source and position. We must take the second approach because
- * we dont know the target here, it's a ref.
- */
- pattern_dump_edge(env->dmp, code, parent, position, edge_mode);
- }
-
- /* dump the node ref */
- pattern_dump_ref(env->dmp, code);
-
- return;
- }
-
- /* get the opcode */
- op_code = get_code(env->buf);
-
- /* get the mode if encoded */
- if (env->options & OPT_WITH_MODE) {
- if (next_tag(env->buf) != VLC_TAG_EMPTY) {
- mode_code = get_code(env->buf);
- }
- }
-
- /* check, if a ICONST attribute is given */
- if (next_tag(env->buf) == VLC_TAG_ICONST) {
- iconst = get_code(env->buf);
- attr = &iconst;
- }
-
- /* dump the edge */
- if (parent) {
- int edge_mode = 0;
-
- /*
- * the mode of a Firm edge can be either computed from its target or
- * from its source and position. We take the second approach because
- * we need it anyway for ref's.
- */
- pattern_dump_edge(env->dmp, env->curr_id, parent, position, edge_mode);
- }
-
- /* dump the node */
- parent = env->curr_id;
- pattern_dump_node(env->dmp, parent, op_code, mode_code, attr);
-
- /* ok, we have a new ID */
- ++env->curr_id;
-
- code = next_tag(env->buf);
- if (code != VLC_TAG_END) {
- /* more info, do recursion */
- int i, preds;
-
- preds = get_code(env->buf);
- if (preds > 0) {
- pattern_start_children(env->dmp, parent);
- for (i = 0; i < preds; ++i) {
- _decode_node(parent, i, env);
- }
- pattern_finish_children(env->dmp, parent);
- }
- }
-}
-
-/**
- * decode an IR-node
- */
-static void decode_node(BYTE *b, unsigned len, pattern_dumper_t *dump)
-{
- codec_env_t env;
- CODE_BUFFER buf;
- unsigned code, options = 0;
-
- init_buf(&buf, b, len);
-
- env.buf = &buf;
- env.curr_id = 1; /* 0 is used for special purpose */
- env.dmp = dump;
-
- /* decode options */
- code = next_tag(&buf);
- if (code == VLC_TAG_OPTION) {
- options = get_code(&buf);
- }
- env.options = options;
-
- _decode_node(0, 0, &env);
-}
-
-/**
- * the environment for the pattern calculation