Signed-off-by: Arthur HUILLET <arthur.huil...@free.fr>
---
Hi, 
        this patch adds a LIR tracer. It has only been implemented for x86 so I 
assume you will have to tweak it a 
        bit before merging it upstream.
        It seems to work fine here, so please apply.


arch/x86/Makefile_32                |    1 +
 arch/x86/include/arch/lir-printer.h |    8 +
 arch/x86/lir-printer.c              |  468 +++++++++++++++++++++++++++++++++++
 include/jit/compiler.h              |    2 +
 jit/compiler.c                      |    3 +
 jit/trace-jit.c                     |   25 ++
 vm/jato.c                           |    1 +
 7 files changed, 508 insertions(+), 0 deletions(-)
 create mode 100644 arch/x86/include/arch/lir-printer.h
 create mode 100644 arch/x86/lir-printer.c

diff --git a/arch/x86/Makefile_32 b/arch/x86/Makefile_32
index d9bbd11..42d681c 100644
--- a/arch/x86/Makefile_32
+++ b/arch/x86/Makefile_32
@@ -3,6 +3,7 @@ ARCH_OBJS = \
        arch/x86/emit-code_32.o         \
        arch/x86/instruction.o          \
        arch/x86/insn-selector_32.o     \
+       arch/x86/lir-printer.o  \
        arch/x86/registers_32.o         \
        arch/x86/stack-frame.o          \
        arch/x86/use-def.o              \
diff --git a/arch/x86/include/arch/lir-printer.h 
b/arch/x86/include/arch/lir-printer.h
new file mode 100644
index 0000000..c4c9afc
--- /dev/null
+++ b/arch/x86/include/arch/lir-printer.h
@@ -0,0 +1,8 @@
+#ifndef __JIT_LIR_PRINTER_H
+#define __JIT_LIR_PRINTER_H
+
+#include <arch/registers.h>
+#include <arch/stack-frame.h>
+
+int lir_print(struct insn *, struct string *);
+#endif
diff --git a/arch/x86/lir-printer.c b/arch/x86/lir-printer.c
new file mode 100644
index 0000000..ac487ea
--- /dev/null
+++ b/arch/x86/lir-printer.c
@@ -0,0 +1,468 @@
+/*
+ * Copyright (c) 2009  Arthur Huillet
+ * Copyright (c) 2006-2008  Pekka Enberg
+ *
+ * This file is released under the GPL version 2 with the following
+ * clarification and special exception:
+ *
+ *     Linking this library statically or dynamically with other modules is
+ *     making a combined work based on this library. Thus, the terms and
+ *     conditions of the GNU General Public License cover the whole
+ *     combination.
+ *
+ *     As a special exception, the copyright holders of this library give you
+ *     permission to link this library with independent modules to produce an
+ *     executable, regardless of the license terms of these independent
+ *     modules, and to copy and distribute the resulting executable under terms
+ *     of your choice, provided that you also meet, for each linked independent
+ *     module, the terms and conditions of the license of that module. An
+ *     independent module is a module which is not derived from or based on
+ *     this library. If you modify this library, you may extend this exception
+ *     to your version of the library, but you are not obligated to do so. If
+ *     you do not wish to do so, delete this exception statement from your
+ *     version.
+ *
+ * Please refer to the file LICENSE for details.
+ */
+
+#include <jit/basic-block.h>
+#include <jit/statement.h>
+#include <jit/compilation-unit.h>
+#include <jit/compiler.h>
+
+#include <vm/list.h>
+#include <vm/buffer.h>
+#include <vm/method.h>
+#include <vm/string.h>
+
+#include <arch/emit-code.h>
+#include <arch/instruction.h>
+#include <arch/memory.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+
+static inline int print_imm(struct string *str, struct operand *op)
+{
+       return str_append(str, "$0x%lx", op->imm);
+}
+
+static inline int print_reg(struct string *str, struct operand *op)
+{
+       return str_append(str, "r%lu", op->reg.interval->var_info->vreg);
+}
+
+static inline int print_membase(struct string *str, struct operand *op)
+{
+       return str_append(str, "$0x%lx(r%lu)", op->disp, 
op->base_reg.interval->var_info->vreg);
+}
+
+static inline int print_memlocal(struct string *str, struct operand *op)
+{
+       return str_append(str, "@%ld(bp)", op->slot->index);
+}
+
+static inline int print_memindex(struct string *str, struct operand *op)
+{
+       return str_append(str, "(r%lu, r%lu, %d)", 
op->base_reg.interval->var_info->vreg, op->index_reg.interval->var_info->vreg, 
op->shift);
+}
+
+static inline int print_rel(struct string *str, struct operand *op)
+{
+       return str_append(str, "$0x%lx", op->rel);
+}
+
+static inline int print_branch(struct string *str, struct operand *op)
+{
+       return str_append(str, "bb 0x%lx", op->branch_target);
+}
+
+static int print_imm_reg(struct string *str, struct insn *insn)
+{
+       print_imm(str, &insn->src);
+       str_append(str, ", ");
+       return print_reg(str, &insn->dest);
+}
+
+static int print_membase_reg(struct string *str, struct insn *insn)
+{
+       print_membase(str, &insn->src);
+       str_append(str, ", ");
+       return print_reg(str, &insn->dest);
+}
+
+static int print_memlocal_reg(struct string *str, struct insn *insn)
+{
+       print_memlocal(str, &insn->src);
+       str_append(str, ", ");
+       return print_reg(str, &insn->dest);
+}
+
+static int print_memindex_reg(struct string *str, struct insn *insn)
+{
+       print_memindex(str, &insn->src);
+       str_append(str, ", ");
+       return print_reg(str, &insn->dest);
+}
+
+static int print_reg_memlocal(struct string *str, struct insn *insn)
+{
+       print_reg(str, &insn->src);
+       str_append(str, ", ");
+       return print_memlocal(str, &insn->dest);
+}
+
+static int print_reg_memindex(struct string *str, struct insn *insn)
+{
+       print_reg(str, &insn->src);
+       str_append(str, ", ");
+       return print_memindex(str, &insn->dest);
+}
+
+static int print_reg_reg(struct string *str, struct insn *insn)
+{
+       print_reg(str, &insn->src);
+       str_append(str, ", ");
+       return print_reg(str, &insn->dest);
+}
+
+#define PRINTFN() str_append(str, "%s ", __FUNCTION__ + 6)
+
+int print_adc_imm_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_imm_reg(str, insn);
+}
+
+int print_adc_membase_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_membase_reg(str, insn);
+}
+
+int print_adc_reg_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_reg_reg(str, insn);
+}
+
+int print_add_imm_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_imm_reg(str, insn);
+}
+
+int print_add_membase_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_membase_reg(str, insn);
+}
+
+int print_add_reg_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_reg_reg(str, insn);
+}
+int print_and_membase_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_membase_reg(str, insn);
+}
+
+int print_call_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       str_append(str, "(");
+       print_reg(str, &insn->operand);
+       return str_append(str, ")");
+}
+
+int print_call_rel(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_rel(str, &insn->operand);
+}
+
+int print_cltd_reg_reg(struct string *str, struct insn *insn)  /* CDQ in Intel 
manuals*/
+{
+       PRINTFN();
+       return print_reg_reg(str, insn);
+}
+
+int print_cmp_imm_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_imm_reg(str, insn);
+}
+
+int print_cmp_membase_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_membase_reg(str, insn);
+}
+
+int print_cmp_reg_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_reg_reg(str, insn);
+}
+
+int print_div_membase_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_membase_reg(str, insn);
+}
+
+int print_je_branch(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_branch(str, &insn->operand);
+}
+
+int print_jge_branch(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_branch(str, &insn->operand);
+}
+
+int print_jg_branch(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_branch(str, &insn->operand);
+}
+
+int print_jle_branch(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_branch(str, &insn->operand);
+}
+
+int print_jl_branch(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_branch(str, &insn->operand);
+}
+
+int print_jmp_branch(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_branch(str, &insn->operand);
+}
+
+int print_jne_branch(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_branch(str, &insn->operand);
+}
+
+int print_mov_imm_membase(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_membase_reg(str, insn);
+}
+
+int print_mov_imm_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_imm_reg(str, insn);
+}
+
+int print_mov_memlocal_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_memlocal_reg(str, insn);
+}
+
+int print_mov_membase_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_membase_reg(str, insn);
+}
+
+int print_mov_memindex_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_memindex_reg(str, insn);
+}
+
+int print_mov_reg_membase(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_membase_reg(str, insn);
+}
+
+int print_mov_reg_memindex(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_reg_memindex(str, insn);
+}
+
+int print_mov_reg_memlocal(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_reg_memlocal(str, insn);
+}
+
+int print_mov_reg_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_reg_reg(str, insn);
+}
+
+int print_mul_membase_eax(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_membase_reg(str, insn);
+}
+
+int print_mul_reg_eax(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_reg_reg(str, insn);
+}
+
+int print_mul_reg_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_reg_reg(str, insn);
+}
+
+int print_neg_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_reg(str, &insn->operand);
+}
+
+int print_or_membase_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_membase_reg(str, insn);
+}
+
+int print_or_reg_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_reg_reg(str, insn);
+}
+
+int print_push_imm(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_imm(str, &insn->operand);
+}
+
+int print_push_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_reg(str, &insn->operand);
+}
+
+int print_sar_imm_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_imm_reg(str, insn);
+}
+
+int print_sar_reg_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_reg_reg(str, insn);
+}
+
+int print_sbb_membase_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_membase_reg(str, insn);
+}
+
+int print_shl_reg_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_reg_reg(str, insn);
+}
+
+int print_shr_reg_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_reg_reg(str, insn);
+}
+
+int print_sub_membase_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_membase_reg(str, insn);
+}
+
+int print_xor_membase_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_membase_reg(str, insn);
+}
+
+int print_xor_imm_reg(struct string *str, struct insn *insn)
+{
+       PRINTFN();
+       return print_imm_reg(str, insn);
+}
+
+typedef int (*print_insn_fn) (struct string *str, struct insn *insn);
+
+static print_insn_fn insn_printers[] = {
+       [INSN_ADC_IMM_REG] = print_adc_imm_reg,
+       [INSN_ADC_MEMBASE_REG] = print_adc_membase_reg,
+       [INSN_ADC_REG_REG] = print_adc_reg_reg,
+       [INSN_ADD_IMM_REG] = print_add_imm_reg,
+       [INSN_ADD_MEMBASE_REG] = print_add_membase_reg,
+       [INSN_ADD_REG_REG] = print_add_reg_reg,
+       [INSN_AND_MEMBASE_REG] = print_and_membase_reg,
+       [INSN_CALL_REG] = print_call_reg,
+       [INSN_CALL_REL] = print_call_rel,
+       [INSN_CLTD_REG_REG] = print_cltd_reg_reg,       /* CDQ in Intel 
manuals*/
+       [INSN_CMP_IMM_REG] = print_cmp_imm_reg,
+       [INSN_CMP_MEMBASE_REG] = print_cmp_membase_reg,
+       [INSN_CMP_REG_REG] = print_cmp_reg_reg,
+       [INSN_DIV_MEMBASE_REG] = print_div_membase_reg,
+       [INSN_JE_BRANCH] = print_je_branch,
+       [INSN_JGE_BRANCH] = print_jge_branch,
+       [INSN_JG_BRANCH] = print_jg_branch,
+       [INSN_JLE_BRANCH] = print_jle_branch,
+       [INSN_JL_BRANCH] = print_jl_branch,
+       [INSN_JMP_BRANCH] = print_jmp_branch,
+       [INSN_JNE_BRANCH] = print_jne_branch,
+       [INSN_MOV_IMM_MEMBASE] = print_mov_imm_membase,
+       [INSN_MOV_IMM_REG] = print_mov_imm_reg,
+       [INSN_MOV_MEMLOCAL_REG] = print_mov_memlocal_reg,
+       [INSN_MOV_MEMBASE_REG] = print_mov_membase_reg,
+       [INSN_MOV_MEMINDEX_REG] = print_mov_memindex_reg,
+       [INSN_MOV_REG_MEMBASE] = print_mov_reg_membase,
+       [INSN_MOV_REG_MEMINDEX] = print_mov_reg_memindex,
+       [INSN_MOV_REG_MEMLOCAL] = print_mov_reg_memlocal,
+       [INSN_MOV_REG_REG] = print_mov_reg_reg,
+       [INSN_MUL_MEMBASE_EAX] = print_mul_membase_eax,
+       [INSN_MUL_REG_EAX] = print_mul_reg_eax,
+       [INSN_MUL_REG_REG] = print_mul_reg_reg,
+       [INSN_NEG_REG] = print_neg_reg,
+       [INSN_OR_MEMBASE_REG] = print_or_membase_reg,
+       [INSN_OR_REG_REG] = print_or_reg_reg,
+       [INSN_PUSH_IMM] = print_push_imm,
+       [INSN_PUSH_REG] = print_push_reg,
+       [INSN_SAR_IMM_REG] = print_sar_imm_reg,
+       [INSN_SAR_REG_REG] = print_sar_reg_reg,
+       [INSN_SBB_MEMBASE_REG] = print_sbb_membase_reg,
+       [INSN_SHL_REG_REG] = print_shl_reg_reg,
+       [INSN_SHR_REG_REG] = print_shr_reg_reg,
+       [INSN_SUB_MEMBASE_REG] = print_sub_membase_reg,
+       [INSN_XOR_MEMBASE_REG] = print_xor_membase_reg,
+       [INSN_XOR_IMM_REG] = print_xor_imm_reg,
+};
+
+int lir_print(struct insn *insn, struct string *str)
+{
+       print_insn_fn print = insn_printers[insn->type];
+
+       return print(str, insn);
+}
diff --git a/include/jit/compiler.h b/include/jit/compiler.h
index 8fadc29..5fa564b 100644
--- a/include/jit/compiler.h
+++ b/include/jit/compiler.h
@@ -72,6 +72,7 @@ static inline void *method_trampoline_ptr(struct methodblock 
*method)
 extern bool opt_trace_method;
 extern bool opt_trace_cfg;
 extern bool opt_trace_tree_ir;
+extern bool opt_trace_lir;
 extern bool opt_trace_liveness;
 extern bool opt_trace_regalloc;
 extern bool opt_trace_machine_code;
@@ -80,6 +81,7 @@ extern bool opt_trace_magic_trampoline;
 void trace_method(struct compilation_unit *);
 void trace_cfg(struct compilation_unit *);
 void trace_tree_ir(struct compilation_unit *);
+void trace_lir(struct compilation_unit *);
 void trace_liveness(struct compilation_unit *);
 void trace_regalloc(struct compilation_unit *);
 void trace_machine_code(struct compilation_unit *);
diff --git a/jit/compiler.c b/jit/compiler.c
index 20af127..7aa8c5b 100644
--- a/jit/compiler.c
+++ b/jit/compiler.c
@@ -51,6 +51,9 @@ int compile(struct compilation_unit *cu)
 
        compute_insn_positions(cu);
 
+       if (opt_trace_lir)
+               trace_lir(cu);
+
        err = analyze_liveness(cu);
        if (err)
                goto out;
diff --git a/jit/trace-jit.c b/jit/trace-jit.c
index 98f5b59..5f7b791 100644
--- a/jit/trace-jit.c
+++ b/jit/trace-jit.c
@@ -16,6 +16,8 @@
 #include <vm/string.h>
 #include <vm/vm.h>
 
+#include <arch/lir-printer.h>
+
 #include "disass.h"
 
 #include <stdbool.h>
@@ -24,6 +26,7 @@
 bool opt_trace_method;
 bool opt_trace_cfg;
 bool opt_trace_tree_ir;
+bool opt_trace_lir;
 bool opt_trace_liveness;
 bool opt_trace_regalloc;
 bool opt_trace_machine_code;
@@ -83,6 +86,28 @@ void trace_tree_ir(struct compilation_unit *cu)
        }
 }
 
+void trace_lir(struct compilation_unit *cu)
+{
+       struct basic_block *bb;
+       struct var_info *var;
+       struct insn *insn;
+       unsigned long offset = 0;
+       struct string *str;
+
+       printf("LIR:\n\n");
+
+       for_each_basic_block(bb, &cu->bb_list) {
+               for_each_insn(insn, &bb->insn_list) {
+                       str = alloc_str();
+                       lir_print(insn, str);
+                       printf("%-2lu \t%s\n", offset++, str->value);
+                       free_str(str);
+               }
+       }
+
+       printf("\n");
+}
+
 void trace_liveness(struct compilation_unit *cu)
 {
        unsigned long offset;
diff --git a/vm/jato.c b/vm/jato.c
index 5db42bc..1c1297f 100644
--- a/vm/jato.c
+++ b/vm/jato.c
@@ -230,6 +230,7 @@ int parseCommandLine(int argc, char *argv[], InitArgs 
*args) {
             opt_trace_method = true;
             opt_trace_cfg = true;
             opt_trace_tree_ir = true;
+                       opt_trace_lir = true;
             opt_trace_liveness = true;
             opt_trace_regalloc = true;
             opt_trace_machine_code = true;
-- 
1.6.2.2


------------------------------------------------------------------------------
Stay on top of everything new and different, both inside and 
around Java (TM) technology - register by April 22, and save
$200 on the JavaOne (SM) conference, June 2-5, 2009, San Francisco.
300 plus technical and hands-on sessions. Register today. 
Use priority code J9JMT32. http://p.sf.net/sfu/p
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to