Sun Jan 16 12:19:35 CET 2005 Paolo Molaro <lupus@ximian.com>
authorPaolo Molaro <lupus@oddwiz.org>
Sun, 16 Jan 2005 11:12:52 +0000 (11:12 -0000)
committerPaolo Molaro <lupus@oddwiz.org>
Sun, 16 Jan 2005 11:12:52 +0000 (11:12 -0000)
* mini.h, mini.c, cfold.c: optimize access to enum
readonly fields, too. Eval conditional branches if possible
to perform unreachable code removal in more cases.

svn path=/trunk/mono/; revision=38986

mono/mini/ChangeLog
mono/mini/cfold.c
mono/mini/mini.c
mono/mini/mini.h

index 5e381f7178766f2eda284a73a4a2aa16a960c34e..942f886939bca8911525daf501b5837053f16a1a 100644 (file)
@@ -1,3 +1,10 @@
+
+Sun Jan 16 12:19:35 CET 2005 Paolo Molaro <lupus@ximian.com>
+
+       * mini.h, mini.c, cfold.c: optimize access to enum
+       readonly fields, too. Eval conditional branches if possible
+       to perform unreachable code removal in more cases.
+
 2005-01-15  Zoltan Varga  <vargaz@freemail.hu>
 
        * tramp-amd64.c exceptions-amd64.c: Use the new global code manager.
index 092c7d7ba13ffd093598045f8981de0f18630605..9ecef4709a08d7df7768a12fa638005f6bf3cae1 100644 (file)
@@ -254,3 +254,64 @@ mono_constant_fold (MonoCompile *cfg)
        }
 }
 
+/*
+ * If the arguments to the cond branch are constants, eval and
+ * return BRANCH_NOT_TAKEN for not taken, BRANCH_TAKEN for taken,
+ * BRANCH_UNDEF otherwise.
+ */
+int
+mono_eval_cond_branch (MonoInst *ins)
+{
+       MonoInst *left, *right;
+       /* FIXME: handle also 64 bit ints */
+       left = ins->inst_left->inst_left;
+       if (left->opcode != OP_ICONST && left->opcode != OP_PCONST)
+               return BRANCH_UNDEF;
+       right = ins->inst_left->inst_right;
+       if (right->opcode != OP_ICONST && right->opcode != OP_PCONST)
+               return BRANCH_UNDEF;
+       switch (ins->opcode) {
+       case CEE_BEQ:
+               if (left->inst_c0 == right->inst_c0)
+                       return BRANCH_TAKEN;
+               return BRANCH_NOT_TAKEN;
+       case CEE_BGE:
+               if (left->inst_c0 >= right->inst_c0)
+                       return BRANCH_TAKEN;
+               return BRANCH_NOT_TAKEN;
+       case CEE_BGT:
+               if (left->inst_c0 > right->inst_c0)
+                       return BRANCH_TAKEN;
+               return BRANCH_NOT_TAKEN;
+       case CEE_BLE:
+               if (left->inst_c0 <= right->inst_c0)
+                       return BRANCH_TAKEN;
+               return BRANCH_NOT_TAKEN;
+       case CEE_BLT:
+               if (left->inst_c0 < right->inst_c0)
+                       return BRANCH_TAKEN;
+               return BRANCH_NOT_TAKEN;
+       case CEE_BNE_UN:
+               if ((gsize)left->inst_c0 != (gsize)right->inst_c0)
+                       return BRANCH_TAKEN;
+               return BRANCH_NOT_TAKEN;
+       case CEE_BGE_UN:
+               if ((gsize)left->inst_c0 >= (gsize)right->inst_c0)
+                       return BRANCH_TAKEN;
+               return BRANCH_NOT_TAKEN;
+       case CEE_BGT_UN:
+               if ((gsize)left->inst_c0 > (gsize)right->inst_c0)
+                       return BRANCH_TAKEN;
+               return BRANCH_NOT_TAKEN;
+       case CEE_BLE_UN:
+               if ((gsize)left->inst_c0 <= (gsize)right->inst_c0)
+                       return BRANCH_TAKEN;
+               return BRANCH_NOT_TAKEN;
+       case CEE_BLT_UN:
+               if ((gsize)left->inst_c0 < (gsize)right->inst_c0)
+                       return BRANCH_TAKEN;
+               return BRANCH_NOT_TAKEN;
+       }
+       return BRANCH_UNDEF;
+}
+
index 5a528051b7181a86285ee7c431ba0694583499f5..7407ad486d1a435d85474abdcba46e5fb36906d8 100644 (file)
@@ -317,12 +317,6 @@ mono_jump_info_token_new (MonoMemPool *mp, MonoImage *image, guint32 token)
                (dest)->type = STACK_I4;        \
        } while (0)
 
-#if SIZEOF_VOID_P == 8
-#define OP_PCONST OP_I8CONST
-#else
-#define OP_PCONST OP_ICONST
-#endif
-
 #define NEW_PCONST(cfg,dest,val) do {  \
                (dest) = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst));       \
                (dest)->opcode = OP_PCONST;     \
@@ -5069,9 +5063,13 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                if (!((cfg->opt & MONO_OPT_SHARED) || cfg->compile_aot) && 
                                    vtable->initialized && (field->type->attrs & FIELD_ATTRIBUTE_INIT_ONLY)) {
                                        gpointer addr = (char*)vtable->data + field->offset;
+                                       int ro_type = field->type->type;
+                                       if (ro_type == MONO_TYPE_VALUETYPE && field->type->data.klass->enumtype) {
+                                               ro_type = field->type->data.klass->enum_basetype->type;
+                                       }
                                        /* g_print ("RO-FIELD %s.%s:%s\n", klass->name_space, klass->name, field->name);*/
                                        is_const = TRUE;
-                                       switch (field->type->type) {
+                                       switch (ro_type) {
                                        case MONO_TYPE_BOOLEAN:
                                        case MONO_TYPE_U1:
                                                NEW_ICONST (cfg, *sp, *((guint8 *)addr));
@@ -7542,6 +7540,23 @@ optimize_branches (MonoCompile *cfg)
                                }
                        } else if (bb->out_count == 2) {
                                if (bb->last_ins && MONO_IS_COND_BRANCH_NOFP (bb->last_ins)) {
+                                       int branch_result = mono_eval_cond_branch (bb->last_ins);
+                                       MonoBasicBlock *taken_branch_target = NULL, *untaken_branch_target = NULL;
+                                       if (branch_result == BRANCH_TAKEN) {
+                                               taken_branch_target = bb->last_ins->inst_true_bb;
+                                               untaken_branch_target = bb->last_ins->inst_false_bb;
+                                       } else if (branch_result == BRANCH_NOT_TAKEN) {
+                                               taken_branch_target = bb->last_ins->inst_false_bb;
+                                               untaken_branch_target = bb->last_ins->inst_true_bb;
+                                       }
+                                       if (taken_branch_target) {
+                                               bb->last_ins->opcode = CEE_BR;
+                                               bb->last_ins->inst_target_bb = taken_branch_target;
+                                               replace_out_block (bb, untaken_branch_target, NULL);
+                                               replace_in_block (untaken_branch_target, bb, NULL);
+                                               changed = TRUE;
+                                               break;
+                                       }
                                        bbn = bb->last_ins->inst_true_bb;
                                        if (bb->region == bbn->region && bbn->code && bbn->code->opcode == CEE_BR &&
                                            bbn->code->inst_target_bb->region == bb->region) {
index a6a9ecafc93bedef3b6b948f5a7141a5059f45c8..f591030b91bdd82f1cfa001f1171f02b9cbdaedb 100644 (file)
 #define inst_ms_word data.op[0].const_val
 #endif
 
+#if SIZEOF_VOID_P == 8
+#define OP_PCONST OP_I8CONST
+#else
+#define OP_PCONST OP_ICONST
+#endif
+
 /* Version number of the AOT file format */
 #define MONO_AOT_FILE_VERSION "15"
 
@@ -697,6 +703,12 @@ typedef struct {
        guint8  pad;
 } MonoJitArgumentInfo;
 
+enum {
+       BRANCH_NOT_TAKEN,
+       BRANCH_TAKEN,
+       BRANCH_UNDEF
+};
+
 typedef void (*MonoInstFunc) (MonoInst *tree, gpointer data);
 
 /* main function */
@@ -713,6 +725,7 @@ int       mono_parse_default_optimizations  (const char* p);
 void      mono_bblock_add_inst              (MonoBasicBlock *bb, MonoInst *inst);
 void      mono_constant_fold                (MonoCompile *cfg);
 void      mono_constant_fold_inst           (MonoInst *inst, gpointer data);
+int       mono_eval_cond_branch             (MonoInst *branch);
 int       mono_is_power_of_two              (guint32 val);
 void      mono_cprop_local                  (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **acp, int acp_size);
 MonoInst* mono_compile_create_var           (MonoCompile *cfg, MonoType *type, int opcode);