2006-07-08 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / mini / aliasing.c
index f1979527082a442c4cd8052aeeb22f71306ddc58..ac1eb3998922c6b47840a1203333c36cf965a49d 100644 (file)
@@ -52,8 +52,19 @@ static const char *mono_stack_type_names[] = {
 #define OP_IS_STORE(op) (((op)==CEE_STIND_REF)||((op)==CEE_STIND_I1)||((op)==CEE_STIND_I2)||((op)==CEE_STIND_I4)||((op)==CEE_STIND_I8)||((op)==CEE_STIND_R4)||((op)==CEE_STIND_R8)||((op)==CEE_STIND_I))
 #define OP_IS_LOAD(op) (((op)==CEE_LDIND_REF)||((op)==CEE_LDIND_I1)||((op)==CEE_LDIND_I2)||((op)==CEE_LDIND_I4)||((op)==CEE_LDIND_U1)||((op)==CEE_LDIND_U2)||((op)==CEE_LDIND_U4)||((op)==CEE_LDIND_I8)||((op)==CEE_LDIND_R4)||((op)==CEE_LDIND_R8)||((op)==CEE_LDIND_I))
 #define OP_IS_CONST(op) (((op)==OP_ICONST)||((op)==OP_I8CONST)||((op)==OP_R4CONST)||((op)==OP_R8CONST)||((op)==OP_AOTCONST))
+#define OP_IS_ICONV(op) (((op)==CEE_CONV_I4)||((op)==CEE_CONV_U4)||((op)==CEE_CONV_I8)||((op)==CEE_CONV_U8)||\
+               ((op)==CEE_CONV_OVF_I4_UN)||((op)==CEE_CONV_OVF_I8_UN)||((op)==CEE_CONV_OVF_U4_UN)||((op)==CEE_CONV_OVF_U8_UN)||\
+               ((op)==CEE_CONV_OVF_I4)||((op)==CEE_CONV_OVF_U4)||((op)==CEE_CONV_OVF_I8)||((op)==CEE_CONV_OVF_U8)||\
+               ((op)==OP_LCONV_TO_I8)||((op)==OP_LCONV_TO_OVF_I8)||((op)==OP_LCONV_TO_OVF_I8_UN)||\
+               ((op)==OP_LCONV_TO_U8)||((op)==OP_LCONV_TO_OVF_U8)||((op)==OP_LCONV_TO_OVF_U8_UN))
+#define OP_IS_PCONV(op) (((op)==CEE_CONV_OVF_I_UN)||((op)==CEE_CONV_OVF_U_UN)||\
+               ((op)==CEE_CONV_I)||((op)==CEE_CONV_U)||\
+               ((op)==CEE_CONV_OVF_I)||((op)==CEE_CONV_OVF_U)||\
+               ((op)==OP_LCONV_TO_I)||((op)==OP_LCONV_TO_OVF_I)||((op)==OP_LCONV_TO_OVF_I_UN)||\
+               ((op)==OP_LCONV_TO_U)||((op)==OP_LCONV_TO_OVF_U)||((op)==OP_LCONV_TO_OVF_U_UN))
 #define LOAD_OF_LOCAL_GIVES_POINTER(load,local) ((local->opcode == OP_LOCAL) && (((load)->type == STACK_MP) || ((load)->type == STACK_PTR) || ((local)->inst_vtype->type == MONO_TYPE_PTR)))
 
+
 /*
  * A struct representing the context of the traversal of a MonoInst tree.
  * Used so that "update_aliasing_information_on_inst" can understand what
@@ -346,7 +357,7 @@ print_code_with_aliasing_information (MonoAliasingInformation *info) {
 #define ADD_ARGUMGENT(info,inst,alias) do {\
                if ((info)->number_of_arguments == (info)->arguments_capacity) {\
                        MonoInst **new_arguments = mono_mempool_alloc ((info)->mempool, sizeof (MonoInst*) * ((info)->arguments_capacity * 2));\
-                       MonoAliasValue *new_arguments_aliases = mono_mempool_alloc ((info)->mempool, sizeof (MonoInst*) * ((info)->arguments_capacity * 2));\
+                       MonoAliasValue *new_arguments_aliases = mono_mempool_alloc ((info)->mempool, sizeof (MonoAliasValue) * ((info)->arguments_capacity * 2));\
                        memcpy (new_arguments, (info)->arguments, sizeof (MonoInst*) * ((info)->arguments_capacity));\
                        memcpy (new_arguments_aliases, (info)->arguments_aliases, sizeof (MonoAliasValue) * ((info)->arguments_capacity));\
                        (info)->arguments = new_arguments;\
@@ -628,7 +639,7 @@ update_aliasing_information_on_inst (MonoAliasingInformation *info, MonoAliasing
                        use->affected_variables = info->temporary_uncontrollably_aliased_variables;
                        APPEND_USE (info,bb_info,use);
                }
-       } else if ((inst->opcode == OP_UNBOXCAST) || (inst->opcode == CEE_CONV_I) || (inst->opcode == OP_LCONV_TO_I)) {
+       } else if ((inst->opcode == OP_UNBOXCAST) || OP_IS_PCONV (inst->opcode) || OP_IS_ICONV (inst->opcode)) {
                father_alias->type = context.subtree_aliases [0].type;
                father_alias->variable_index = context.subtree_aliases [0].variable_index;
        } else if ((inst->opcode == CEE_LDELEMA) || (inst->opcode == OP_COMPARE) || (inst->opcode == CEE_SWITCH)) {
@@ -638,9 +649,21 @@ update_aliasing_information_on_inst (MonoAliasingInformation *info, MonoAliasing
        } else {
                MonoAliasType father_type = MONO_ALIASING_TYPE_NO_ALIAS;
                if ((context.subtree_aliases [0].type == MONO_ALIASING_TYPE_LOCAL) || (context.subtree_aliases [0].type == MONO_ALIASING_TYPE_LOCAL_FIELD)) {
+                       MonoAliasUsageInformation *use = mono_mempool_alloc (info->mempool, sizeof (MonoAliasUsageInformation));
+                       
+                       inst->ssa_op = MONO_SSA_INDIRECT_LOAD_STORE;
+                       use->inst = inst;
+                       use->affected_variables = &(info->variables [context.subtree_aliases [0].variable_index]);
+                       APPEND_USE (info, bb_info, use);
                        ADD_BAD_ALIAS (info, context.subtree_aliases [0].variable_index);
                }
                if ((context.subtree_aliases [1].type == MONO_ALIASING_TYPE_LOCAL) || (context.subtree_aliases [1].type == MONO_ALIASING_TYPE_LOCAL_FIELD)) {
+                       MonoAliasUsageInformation *use = mono_mempool_alloc (info->mempool, sizeof (MonoAliasUsageInformation));
+                       
+                       inst->ssa_op = MONO_SSA_INDIRECT_LOAD_STORE;
+                       use->inst = inst;
+                       use->affected_variables = &(info->variables [context.subtree_aliases [1].variable_index]);
+                       APPEND_USE (info, bb_info, use);
                        ADD_BAD_ALIAS (info, context.subtree_aliases [1].variable_index);
                }
                if (father_alias != NULL) { 
@@ -803,7 +826,7 @@ mono_aliasing_get_affected_variables_for_inst_traversing_code (MonoAliasingInfor
        }
 }
 
-MonoLocalVariableList*
+static MonoLocalVariableList*
 mono_aliasing_get_affected_variables_for_inst_in_bb (MonoAliasingInformation *info, MonoInst *inst, MonoBasicBlock *bb) {
        MonoAliasUsageInformation *use;
        
@@ -873,10 +896,17 @@ mono_aliasing_deadce_on_inst (MonoAliasingInformation *info, MonoInst **possibly
        
        arity = mono_burg_arity [inst->opcode];
        
-       if (OP_IS_CALL (inst->opcode)) {
-               has_side_effects = TRUE;
-       } else {
+       switch (inst->opcode) {
+#define OPDEF(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) case a1:
+#include "simple-cee-ops.h"
+#undef OPDEF
+#define MINI_OP(a1,a2) case a1:
+#include "simple-mini-ops.h"
+#undef MINI_OP
                has_side_effects = FALSE;
+               break;
+       default:
+               has_side_effects = TRUE;
        }
        
        if (arity) {