From b277d2897da73dae48d2abbe735ddfb40fcd096a Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Fri, 6 Jun 2003 13:05:31 +0000 Subject: [PATCH] 2003-06-06 Dietmar Maurer * mini.c (mono_method_to_ir): inline static readonly fields * ssa.c (fold_tree): start cfold support for long (very simple cases only) * cfold.c (mono_constant_fold_inst): opt. CEE_CONV_I8 (OP_ICONST) svn path=/trunk/mono/; revision=15157 --- mono/benchmark/Makefile.am | 1 + mono/benchmark/readonly.cs | 27 +++++++++++ mono/mini/ChangeLog | 8 ++++ mono/mini/cfold.c | 18 +++++--- mono/mini/mini.c | 92 ++++++++++++++++++++++++++++++++------ mono/mini/ssa.c | 52 ++++++++++++++++++--- 6 files changed, 175 insertions(+), 23 deletions(-) create mode 100755 mono/benchmark/readonly.cs diff --git a/mono/benchmark/Makefile.am b/mono/benchmark/Makefile.am index 4db8e150a63..68c057bd476 100644 --- a/mono/benchmark/Makefile.am +++ b/mono/benchmark/Makefile.am @@ -21,6 +21,7 @@ TESTSRC= \ logic.cs \ switch.cs \ ctor-bench.cs \ + readonly.cs \ bulkcpy.il \ math.cs diff --git a/mono/benchmark/readonly.cs b/mono/benchmark/readonly.cs new file mode 100755 index 00000000000..11ed40d7761 --- /dev/null +++ b/mono/benchmark/readonly.cs @@ -0,0 +1,27 @@ +using System; + +public class Test { + + static readonly int a = 5; + static readonly int b = 6; + + public static int Main (string[] args) { + int repeat = 1; + + if (args.Length == 1) + repeat = Convert.ToInt32 (args [0]); + + Console.WriteLine ("Repeat = " + repeat); + + for (int i = 0; i < repeat*3; i++) { + for (int j = 0; j < 100000000; j++) { + if ((a != 5) || (b != 6)) + return 1; + } + } + + return 0; + } +} + + diff --git a/mono/mini/ChangeLog b/mono/mini/ChangeLog index a0cffc5dd54..785628cfb2a 100644 --- a/mono/mini/ChangeLog +++ b/mono/mini/ChangeLog @@ -1,3 +1,11 @@ +2003-06-06 Dietmar Maurer + + * mini.c (mono_method_to_ir): inline static readonly fields + + * ssa.c (fold_tree): start cfold support for long (very simple + cases only) + + * cfold.c (mono_constant_fold_inst): opt. CEE_CONV_I8 (OP_ICONST) Fri Jun 6 11:41:18 CEST 2003 Paolo Molaro diff --git a/mono/mini/cfold.c b/mono/mini/cfold.c index 86471e810e9..ce794d1c7da 100644 --- a/mono/mini/cfold.c +++ b/mono/mini/cfold.c @@ -118,11 +118,13 @@ is_power_of_two (guint32 val) #define FOLD_UNOP(name,op) \ case name: \ - if (inst->inst_i0->opcode != OP_ICONST) \ - return; \ - inst->opcode = OP_ICONST; \ - inst->inst_c0 = op inst->inst_i0->inst_c0; \ - return; + if (inst->inst_i0->opcode == OP_ICONST) { \ + inst->opcode = OP_ICONST; \ + inst->inst_c0 = op inst->inst_i0->inst_c0; \ + } else if (inst->inst_i0->opcode == OP_I8CONST) { \ + inst->opcode = OP_I8CONST; \ + inst->inst_l = op inst->inst_i0->inst_l; \ + } return; #define FOLD_BRBINOP(name,op,cast) \ case name: \ @@ -188,6 +190,12 @@ mono_constant_fold_inst (MonoInst *inst, gpointer data) FOLD_CXX (OP_CGT_UN,>,guint32) FOLD_CXX (OP_CLT,<,gint32) FOLD_CXX (OP_CLT_UN,<,guint32) + case CEE_CONV_I8: + if (inst->inst_i0->opcode == OP_ICONST) { + inst->opcode = OP_I8CONST; + inst->inst_l = inst->inst_i0->inst_c0; + } + return; /* we should be able to handle isinst and castclass as well */ case CEE_ISINST: case CEE_CASTCLASS: diff --git a/mono/mini/mini.c b/mono/mini/mini.c index fe23d1734b3..f4c73c69e70 100644 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -3345,17 +3345,17 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b case CEE_CONV_I1: case CEE_CONV_I2: case CEE_CONV_I4: - case CEE_CONV_I8: case CEE_CONV_R4: case CEE_CONV_R8: case CEE_CONV_U4: + case CEE_CONV_I8: case CEE_CONV_U8: case CEE_CONV_OVF_I8: case CEE_CONV_OVF_U8: case CEE_CONV_R_UN: CHECK_STACK (1); ADD_UNOP (*ip); - ip++; + ip++; break; case CEE_CONV_OVF_I4: case CEE_CONV_OVF_I1: @@ -3864,17 +3864,83 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b } else MONO_ADD_INS (bblock, store); } else { - MonoInst *load; - CHECK_STACK_OVF (1); - MONO_INST_NEW (cfg, load, mono_type_to_ldind (field->type)); - type_to_eval_stack_type (field->type, load); - load->cil_code = ip; - load->inst_left = ins; - *sp++ = load; - load->flags |= ins_flag; - ins_flag = 0; - /* fixme: dont see the problem why this does not work */ - //cfg->disable_aot = TRUE; + gboolean is_const = FALSE; + MonoVTable *vtable = mono_class_vtable (cfg->domain, klass); + if (!((cfg->opt & MONO_OPT_SHARED) || mono_compile_aot) && + vtable->initialized && (field->type->attrs & FIELD_ATTRIBUTE_INIT_ONLY)) { + gpointer addr = (char*)vtable->data + field->offset; + /* g_print ("RO-FIELD %s.%s:%s\n", klass->name_space, klass->name, field->name);*/ + is_const = TRUE; + switch (field->type->type) { + case MONO_TYPE_BOOLEAN: + case MONO_TYPE_U1: + NEW_ICONST (cfg, *sp, *((guint8 *)addr)); + sp++; + break; + case MONO_TYPE_I1: + NEW_ICONST (cfg, *sp, *((gint8 *)addr)); + sp++; + break; + case MONO_TYPE_CHAR: + case MONO_TYPE_U2: + NEW_ICONST (cfg, *sp, *((guint16 *)addr)); + sp++; + break; + case MONO_TYPE_I2: + NEW_ICONST (cfg, *sp, *((gint16 *)addr)); + sp++; + break; + break; + case MONO_TYPE_I4: + NEW_ICONST (cfg, *sp, *((gint32 *)addr)); + sp++; + break; + case MONO_TYPE_U4: + NEW_ICONST (cfg, *sp, *((guint32 *)addr)); + sp++; + break; + case MONO_TYPE_I: + case MONO_TYPE_U: + case MONO_TYPE_STRING: + case MONO_TYPE_OBJECT: + case MONO_TYPE_CLASS: + case MONO_TYPE_SZARRAY: + case MONO_TYPE_PTR: + case MONO_TYPE_FNPTR: + case MONO_TYPE_ARRAY: + NEW_PCONST (cfg, *sp, *((gpointer *)addr)); + type_to_eval_stack_type (field->type, *sp); + sp++; + break; + case MONO_TYPE_I8: + case MONO_TYPE_U8: + MONO_INST_NEW (cfg, *sp, OP_I8CONST); + sp [0]->type = STACK_I8; + sp [0]->inst_l = *((gint64 *)addr); + sp++; + break; + case MONO_TYPE_R4: + case MONO_TYPE_R8: + case MONO_TYPE_VALUETYPE: + default: + is_const = FALSE; + break; + } + } + + if (!is_const) { + MonoInst *load; + CHECK_STACK_OVF (1); + MONO_INST_NEW (cfg, load, mono_type_to_ldind (field->type)); + type_to_eval_stack_type (field->type, load); + load->cil_code = ip; + load->inst_left = ins; + *sp++ = load; + load->flags |= ins_flag; + ins_flag = 0; + /* fixme: dont see the problem why this does not work */ + //cfg->disable_aot = TRUE; + } } ip += 5; break; diff --git a/mono/mini/ssa.c b/mono/mini/ssa.c index 1d0b68f6684..2b9bb373b04 100644 --- a/mono/mini/ssa.c +++ b/mono/mini/ssa.c @@ -729,6 +729,37 @@ simulate_compare (int opcode, int a, int b) return 0; } +static int +simulate_long_compare (int opcode, gint64 a, gint64 b) +{ + switch (opcode) { + case CEE_BEQ: + return a == b; + case CEE_BGE: + return a >= b; + case CEE_BGT: + return a > b; + case CEE_BLE: + return a <= b; + case CEE_BLT: + return a < b; + case CEE_BNE_UN: + return a != b; + case CEE_BGE_UN: + return (unsigned)a >= (unsigned)b; + case CEE_BGT_UN: + return (unsigned)a > (unsigned)b; + case CEE_BLE_UN: + return (unsigned)a <= (unsigned)b; + case CEE_BLT_UN: + return (unsigned)a < (unsigned)b; + default: + g_assert_not_reached (); + } + + return 0; +} + #define EVAL_CXX(name,op,cast) \ case name: \ if (inst->inst_i0->opcode == OP_COMPARE) { \ @@ -756,6 +787,7 @@ simulate_compare (int opcode, int a, int b) break; +/* fixme: this only works for interger constants, but not for other types (long, float) */ static int evaluate_const_tree (MonoCompile *cfg, MonoInst *inst, int *res, MonoInst **carray) { @@ -834,11 +866,19 @@ fold_tree (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *inst, MonoInst **carr inst->inst_i0->opcode == OP_COMPARE) { MonoInst *v0 = inst->inst_i0->inst_i0; MonoInst *v1 = inst->inst_i0->inst_i1; + MonoBasicBlock *target = NULL; - if (evaluate_const_tree (cfg, v0, &a, carray) == 1 && - evaluate_const_tree (cfg, v1, &b, carray) == 1) { - MonoBasicBlock *target; - + /* hack for longs to optimize the simply cases */ + if (v0->opcode == OP_I8CONST && v1->opcode == OP_I8CONST) { + if (simulate_long_compare (inst->opcode, v0->inst_l, v1->inst_l)) { + //unlink_target (bb, inst->inst_false_bb); + target = inst->inst_true_bb; + } else { + //unlink_target (bb, inst->inst_true_bb); + target = inst->inst_false_bb; + } + } else if (evaluate_const_tree (cfg, v0, &a, carray) == 1 && + evaluate_const_tree (cfg, v1, &b, carray) == 1) { if (simulate_compare (inst->opcode, a, b)) { //unlink_target (bb, inst->inst_false_bb); target = inst->inst_true_bb; @@ -846,7 +886,9 @@ fold_tree (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *inst, MonoInst **carr //unlink_target (bb, inst->inst_true_bb); target = inst->inst_false_bb; } - + } + + if (target) { bb->out_bb [0] = target; bb->out_count = 1; inst->opcode = CEE_BR; -- 2.25.1