@@ -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)
@@ -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
@@ -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
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(+)