diff mbox

[RFC,2/3] tb-annotation: Add control flow graph mapper

Message ID 1452768923-13787-3-git-send-email-peer.adelt@c-lab.de
State New
Headers show

Commit Message

Peer Adelt Jan. 14, 2016, 10:55 a.m. UTC
Added helper function at the start of every TranslationBlock
that maps the sequence of static basic blocks (obtained from
the XML file) to the current TranslationBlock. The helper also
accumulates the values that are annotated on the corresponding
edges of the control flow graph.

Signed-off-by: Peer Adelt <peer.adelt@c-lab.de>
---
 include/exec/gen-icount.h | 18 +++++++++
 tcg-runtime.c             | 99 +++++++++++++++++++++++++++++++++++++++++++++++
 tcg/tcg-runtime.h         |  4 ++
 3 files changed, 121 insertions(+)
diff mbox

Patch

diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index 05d89d3..0b8821b 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -14,6 +14,11 @@  static inline void gen_tb_start(TranslationBlock *tb)
     TCGv_i32 count, flag, imm;
     int i;
 
+#ifdef CONFIG_TB_ANNOTATION
+    TCGv_ptr annotation_ptr;
+    TCGv_i64 pc;
+#endif
+
     exitreq_label = gen_new_label();
     flag = tcg_temp_new_i32();
     tcg_gen_ld_i32(flag, cpu_env,
@@ -21,6 +26,17 @@  static inline void gen_tb_start(TranslationBlock *tb)
     tcg_gen_brcondi_i32(TCG_COND_NE, flag, 0, exitreq_label);
     tcg_temp_free_i32(flag);
 
+#ifdef CONFIG_TB_ANNOTATION
+    pc = tcg_const_i64(tb->pc);
+    annotation_ptr = tcg_temp_new_ptr();
+    tcg_gen_ld_ptr(annotation_ptr, cpu_env,
+                   -ENV_OFFSET + offsetof(CPUState, tb_annotation));
+
+    gen_helper_annotation(pc, annotation_ptr);
+    tcg_temp_free_i64(pc);
+    tcg_temp_free_ptr(annotation_ptr);
+#endif
+
     if (!(tb->cflags & CF_USE_ICOUNT)) {
         return;
     }
@@ -45,6 +61,8 @@  static inline void gen_tb_start(TranslationBlock *tb)
     tcg_gen_st16_i32(count, cpu_env,
                      -ENV_OFFSET + offsetof(CPUState, icount_decr.u16.low));
     tcg_temp_free_i32(count);
+
+
 }
 
 static void gen_tb_end(TranslationBlock *tb, int num_insns)
diff --git a/tcg-runtime.c b/tcg-runtime.c
index 9daba69..fc2526c 100644
--- a/tcg-runtime.c
+++ b/tcg-runtime.c
@@ -29,6 +29,10 @@ 
 
 #include "exec/helper-head.h"
 
+#ifdef CONFIG_TB_ANNOTATION
+#include "tb-annotation/tb-annotation.h"
+#endif
+
 #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
   dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2));
 
@@ -107,3 +111,98 @@  int64_t HELPER(mulsh_i64)(int64_t arg1, int64_t arg2)
     muls64(&l, &h, arg1, arg2);
     return h;
 }
+
+#ifdef CONFIG_TB_ANNOTATION
+static inline void take_final_edge(TbAnnotation *env, TbAnnotationEdge *edge)
+{
+    /* Store current context and block */
+    env->last_ctx = edge->target_context;
+    env->last_block = edge->target;
+    /* Accumulate value */
+    env->value_sum += edge->value;
+}
+
+static inline void take_edge(TbAnnotation *env, TbAnnotationEdge *edge)
+{
+    TbAnnotationLeavingEdgeTuple *out;
+
+    /* Store current context and block */
+    env->last_ctx = edge->target_context;
+    env->last_block = edge->target;
+    /* Accumulate value */
+    env->value_sum += edge->value;
+
+    /* Check whether we are at the end of our analysis... */
+    if (env->last_block->out_edges_hash_table != NULL) {
+        out = g_hash_table_lookup(env->last_block->out_edges_hash_table,
+                                  env->last_ctx);
+        if (out != NULL && out->out1->target->is_end_block) {
+            take_final_edge(env, out->out1);
+        }
+    }
+}
+
+void HELPER(annotation)(uint64_t pc, void *opaque)
+{
+    TbAnnotation *env = (TbAnnotation *) opaque;
+    TbAnnotationBlock *b;
+    TbAnnotationLeavingEdgeTuple *out;
+
+    if (!env) {
+        return;
+    }
+
+    /* does the block corresponding to pc exist? */
+    if (!g_hash_table_contains(env->tb_annotation_blocks, &pc)) {
+        return;
+    }
+    /* if last_block == NULL we're in the first block */
+    if (env->last_block == NULL) {
+
+        b = (TbAnnotationBlock *)g_hash_table_lookup(env->tb_annotation_blocks,
+                                                     &pc);
+        env->last_block = b;
+
+    } else {
+        /* while not reached block with current pc (target)
+         * take the next distinct edge if it exists
+         * otherwise we're one edge away from the target and
+         * take the edge directly leading to the target
+         */
+        out = g_hash_table_lookup(env->last_block->out_edges_hash_table,
+                                  env->last_ctx);
+
+        while (out != NULL && out->out2 == NULL) {
+            /* We found a distinct path to "out1" */
+            take_edge(env, out->out1);
+
+            /* Have we reached our target? */
+            if (env->last_block->address == pc) {
+                return;
+            }
+
+            /* Get the current out edge tuple */
+            out = g_hash_table_lookup(env->last_block->out_edges_hash_table,
+                                      env->last_ctx);
+        }
+
+        /* If we get here, we are on a branch block.
+           Take the edge leading to the target. */
+        if (out != NULL && out->out1->target->address == pc) {
+
+            /* Take this edge */
+            take_edge(env, out->out1);
+
+
+        } else if (out != NULL && out->out2->target->address == pc) {
+
+            /* Take the other edge */
+            take_edge(env, out->out2);
+
+        } else {
+
+            /* Something went terribly wrong here... */
+        }
+    }
+        }
+#endif
diff --git a/tcg/tcg-runtime.h b/tcg/tcg-runtime.h
index 23a0c37..004bf8f 100644
--- a/tcg/tcg-runtime.h
+++ b/tcg/tcg-runtime.h
@@ -14,3 +14,7 @@  DEF_HELPER_FLAGS_2(sar_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
 
 DEF_HELPER_FLAGS_2(mulsh_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
 DEF_HELPER_FLAGS_2(muluh_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
+
+#ifdef CONFIG_TB_ANNOTATION
+DEF_HELPER_2(annotation, void, i64, ptr)
+#endif