From: Marcos Henrich Date: Wed, 19 Aug 2015 19:05:42 +0000 (+0100) Subject: [runtime] Added MONO_DEBUG=single-imm-size. X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;ds=sidebyside;h=60799f34d700eb1255ce4b3e8f628c2c8f3df796;p=mono.git [runtime] Added MONO_DEBUG=single-imm-size. In amd64 when i8const are use with values within the first 32 bits instructions and registers used can be optimized to their 32 bit versions. Setting MONO_DEBUG=single-imm-size variable disables such optimizations and guarantee that the the generated native code size is independent of the i8const values. --- diff --git a/mono/mini/mini-amd64.c b/mono/mini/mini-amd64.c index 9d39b9e210d..57d1a8f5df9 100644 --- a/mono/mini/mini-amd64.c +++ b/mono/mini/mini-amd64.c @@ -182,6 +182,15 @@ amd64_is_near_call (guint8 *code) return code [0] == 0xe8; } +static inline gboolean +amd64_use_imm32 (gint64 val) +{ + if (mini_get_debug_options()->single_imm_size) + return FALSE; + + return amd64_is_imm32 (val); +} + #ifdef __native_client_codegen__ /* Keep track of instruction "depth", that is, the level of sub-instruction */ @@ -3185,7 +3194,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) break; case OP_COMPARE_IMM: case OP_LCOMPARE_IMM: - if (!amd64_is_imm32 (ins->inst_imm)) { + if (!amd64_use_imm32 (ins->inst_imm)) { NEW_INS (cfg, ins, temp, OP_I8CONST); temp->inst_c0 = ins->inst_imm; temp->dreg = mono_alloc_ireg (cfg); @@ -3200,7 +3209,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) #ifndef __native_client_codegen__ /* Don't generate memindex opcodes (to simplify */ /* read sandboxing) */ - if (!amd64_is_imm32 (ins->inst_offset)) { + if (!amd64_use_imm32 (ins->inst_offset)) { NEW_INS (cfg, ins, temp, OP_I8CONST); temp->inst_c0 = ins->inst_offset; temp->dreg = mono_alloc_ireg (cfg); @@ -3213,7 +3222,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) case OP_STORE_MEMBASE_IMM: #endif case OP_STOREI8_MEMBASE_IMM: - if (!amd64_is_imm32 (ins->inst_imm)) { + if (!amd64_use_imm32 (ins->inst_imm)) { NEW_INS (cfg, ins, temp, OP_I8CONST); temp->inst_c0 = ins->inst_imm; temp->dreg = mono_alloc_ireg (cfg); @@ -3846,10 +3855,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) #endif case OP_LOADI8_MEM: // FIXME: Decompose this earlier - if (amd64_is_imm32 (ins->inst_imm)) + if (amd64_use_imm32 (ins->inst_imm)) amd64_mov_reg_mem (code, ins->dreg, ins->inst_imm, 8); else { - amd64_mov_reg_imm (code, ins->dreg, ins->inst_imm); + amd64_mov_reg_imm_size (code, ins->dreg, ins->inst_imm, sizeof(gpointer)); amd64_mov_reg_membase (code, ins->dreg, ins->dreg, 0, 8); } break; @@ -3859,10 +3868,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) break; case OP_LOADU4_MEM: // FIXME: Decompose this earlier - if (amd64_is_imm32 (ins->inst_imm)) + if (amd64_use_imm32 (ins->inst_imm)) amd64_mov_reg_mem (code, ins->dreg, ins->inst_imm, 4); else { - amd64_mov_reg_imm (code, ins->dreg, ins->inst_imm); + amd64_mov_reg_imm_size (code, ins->dreg, ins->inst_imm, sizeof(gpointer)); amd64_mov_reg_membase (code, ins->dreg, ins->dreg, 0, 4); } break; @@ -4593,7 +4602,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_ICONST: case OP_I8CONST: - if ((((guint64)ins->inst_c0) >> 32) == 0) + if (amd64_use_imm32 (ins->inst_c0)) amd64_mov_reg_imm_size (code, ins->dreg, ins->inst_c0, 4); else amd64_mov_reg_imm_size (code, ins->dreg, ins->inst_c0, 8); @@ -7679,7 +7688,7 @@ mono_arch_flush_register_windows (void) gboolean mono_arch_is_inst_imm (gint64 imm) { - return amd64_is_imm32 (imm); + return amd64_use_imm32 (imm); } /* @@ -8061,7 +8070,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI if (item->is_equals) { if (item->check_target_idx) { if (!item->compare_done) { - if (amd64_is_imm32 (item->key)) + if (amd64_use_imm32 ((gint64)item->key)) item->chunk_size += CMP_SIZE; else item->chunk_size += MOV_REG_IMM_SIZE + CMP_REG_REG_SIZE; @@ -8097,7 +8106,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI } } } else { - if (amd64_is_imm32 (item->key)) + if (amd64_use_imm32 ((gint64)item->key)) item->chunk_size += CMP_SIZE; else item->chunk_size += MOV_REG_IMM_SIZE + CMP_REG_REG_SIZE; @@ -8125,10 +8134,10 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI if (item->check_target_idx || fail_case) { if (!item->compare_done || fail_case) { - if (amd64_is_imm32 (item->key)) + if (amd64_use_imm32 ((gint64)item->key)) amd64_alu_reg_imm_size (code, X86_CMP, MONO_ARCH_IMT_REG, (guint32)(gssize)item->key, sizeof(gpointer)); else { - amd64_mov_reg_imm (code, MONO_ARCH_IMT_SCRATCH_REG, item->key); + amd64_mov_reg_imm_size (code, MONO_ARCH_IMT_SCRATCH_REG, item->key, sizeof(gpointer)); amd64_alu_reg_reg (code, X86_CMP, MONO_ARCH_IMT_REG, MONO_ARCH_IMT_SCRATCH_REG); } } @@ -8176,10 +8185,10 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI #endif } } else { - if (amd64_is_imm32 (item->key)) + if (amd64_use_imm32 ((gint64)item->key)) amd64_alu_reg_imm_size (code, X86_CMP, MONO_ARCH_IMT_REG, (guint32)(gssize)item->key, sizeof (gpointer)); else { - amd64_mov_reg_imm (code, MONO_ARCH_IMT_SCRATCH_REG, item->key); + amd64_mov_reg_imm_size (code, MONO_ARCH_IMT_SCRATCH_REG, item->key, sizeof (gpointer)); amd64_alu_reg_reg (code, X86_CMP, MONO_ARCH_IMT_REG, MONO_ARCH_IMT_SCRATCH_REG); } item->jmp_code = code; diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c index 0111f51a488..27bc1fb5b2a 100644 --- a/mono/mini/mini-runtime.c +++ b/mono/mini/mini-runtime.c @@ -2659,6 +2659,8 @@ mini_parse_debug_options (void) debug_options.gen_sdb_seq_points = TRUE; else if (!strcmp (arg, "gen-compact-seq-points")) debug_options.gen_seq_points_compact_data = TRUE; + else if (!strcmp (arg, "single-imm-size")) + debug_options.single_imm_size = TRUE; else if (!strcmp (arg, "init-stacks")) debug_options.init_stacks = TRUE; else if (!strcmp (arg, "casts")) diff --git a/mono/mini/mini.h b/mono/mini/mini.h index 386f80c7e1a..7a9df93158c 100644 --- a/mono/mini/mini.h +++ b/mono/mini/mini.h @@ -1924,6 +1924,11 @@ typedef struct { */ gboolean gen_sdb_seq_points; gboolean gen_seq_points_compact_data; + /* + * Setting single_imm_size should guarantee that each time managed code is compiled + * the same instructions and registers are used, regardless of the size of used values. + */ + gboolean single_imm_size; gboolean explicit_null_checks; /* * Fill stack frames with 0x2a in method prologs. This helps with the