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