Signed-off-by: Arthur HUILLET <[email protected]>
---
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/jatovm-devel