+
+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.
}
}
+/*
+ * 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;
+}
+
(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; \
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));
}
} 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) {
#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"
guint8 pad;
} MonoJitArgumentInfo;
+enum {
+ BRANCH_NOT_TAKEN,
+ BRANCH_TAKEN,
+ BRANCH_UNDEF
+};
+
typedef void (*MonoInstFunc) (MonoInst *tree, gpointer data);
/* main function */
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);